Author Topic: Click It!  (Read 3773 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Click It!
« on: November 27, 2019, 12:09:27 am »
Code: QB64: [Select]
  1. CONST DefaultPort$ = "7993"
  2. CONST DefaultIP$ = "172.93.60.23"
  3. CONST True = -1, False = 0
  4. CONST Verbose = True
  5. _DEFINE A-Z AS _INTEGER64  'we're going to send/recieve int64s usually (8 bytes).  Deal with it.
  6. DIM SHARED Host, Client, LastSeen
  7.  
  8.  
  9. 'REQUIRED SERVER CODE ABOVE
  10.  
  11.  
  12.  
  13. SCREEN _NEWIMAGE(800, 600, 32)
  14.  
  15. _TITLE "Click It!"
  16. _CONTROLCHR OFF 'not necessary, but used here to help diagnose stray characters passed back and forth
  17.  
  18. PRINT "Connecting to Server..";
  19. Client = ConnectAsClient(DefaultPort, DefaultIP$)
  20. PRINT Verify$
  21. PRINT "Press <ANY KEY> to continue..."
  22.  
  23.  
  24. PRINT "Are you a new player?  (Y/N)"
  25.     a$ = UCASE$(INPUT$(1))
  26. LOOP UNTIL a$ = "Y" OR a$ = "N"
  27.     IF a$ = "Y" THEN
  28.         INPUT "REGISTER NAME:"; n$
  29.         INPUT "REGISTER PASSWORD:"; p$
  30.         Send Client, "[REGISTER]" + n$ + "," + p$ 'Register a new account
  31.     ELSE
  32.         INPUT "LOGIN NAME:"; n$
  33.         INPUT "LOGIN PASSWORD:"; p$
  34.         Send Client, "[LOG IN]" + n$ + "," + p$ 'Login from an existing account
  35.     END IF
  36.     OK$ = Verify$
  37.     PRINT OK$ 'don't just print the results here
  38. LOOP UNTIL LEFT$(OK$, 4) = "[OK]" 'we want to actually make use of them.
  39. PRINT "Press <ANY KEY> to continue..."
  40.  
  41. Send Client, "[GAME SET]Click It" 'Let the server know what game we're playing.
  42. PRINT Verify$
  43. Send Client, "[GAME GET]Highscore.txt"
  44. OK$ = Verify$ 'same deal as above.  We don't want to just print the results; we want to use them.
  45. IF LEFT$(OK$, 4) = "[OK]" THEN highscore$ = MID$(OK$, 5) 'the server just sent us the whole highscore listing,
  46. 'all at once.  We can write it to our disk if we want (OPEN file$ FOR BINARY and PUT the whole file to drive),
  47. 'or we can parse it as we want, to make sense of who/what it is.
  48. 'What this file contains is what we sent to the server to store for us, so if we don't know how to decipher it
  49. 'for our game, the server sure as hell doesn't know what to do with it either!
  50. PRINT "Highscore.txt retrieved."
  51. PRINT "Press <ANY KEY> to continue..."
  52.  
  53. 'At this point, highscore.txt is either going to be one of two different things:
  54. '1) It's going to be blank and have a file length of 0, as we haven't saved any highscores yet.
  55. '2) It's going to be the whole highscore list.
  56.  
  57. 'Regardless, let's go ahead and just save file this to our drive as file handle #1.  (Our only needed filehandle)
  58.  
  59. OPEN "highscore.txt" FOR OUTPUT AS #1: CLOSE 1 'blank any old highscore file.
  60. OPEN "highscore.txt" FOR BINARY AS #1
  61. PUT #1, , highscore$ 'and put the whole file to the drive all at once.
  62.  
  63. 'AGAIN, You'll need to come up with your own method to handle however you process the file the server sent you.
  64. 'This is just the simple style which I chose to use for this demo.
  65.  
  66. SEEK #1, 1 'This isn't the most efficient way to get my high score list, but it's the one I'm using
  67. DIM Player$(1000), Score(1000) 'Up to 1000 players, and their score.
  68. DO UNTIL EOF(1) OR LOF(1) = 0
  69.     players = players + 1
  70.     LINE INPUT #1, Player$(players)
  71.     LINE INPUT #1, junk$
  72.     Score(players) = VAL(junk$)
  73.     IF Player$(players) = n$ THEN click = Score(players): found = players
  74.  
  75. COLOR , 0
  76.     CLS
  77.     LINE (100, 100)-(300, 200), &HFF00FF00, BF
  78.     LINE (100, 100)-(300, 200), -1, B
  79.     _PRINTSTRING (110, 140), "<CLICKS:" + STR$(click) + ">"
  80.     IF _MOUSEBUTTON(1) <> 0 AND oldmouse = 0 THEN 'mouse is clicked
  81.         IF _MOUSEX >= 100 AND _MOUSEX <= 300 AND _MOUSEY >= 100 AND _MOUSEY <= 200 THEN 'it's a click in the box
  82.             click = click + 1
  83.         ELSE 'we clicked outside the box!  We have to quit!
  84.             EXIT DO
  85.         END IF
  86.     END IF
  87.     oldmouse = _MOUSEBUTTON(1)
  88.     _DISPLAY
  89.     _LIMIT 60
  90.  
  91. IF found THEN
  92.     Score(found) = click
  93.     players = players + 1
  94.     Score(players) = click
  95.     Player$(players) = n$
  96.  
  97. FOR i = 1 TO players - 1 'a lazy bubble sort to rank our players.
  98.     FOR j = i TO players 'this is inefficient as heck, but I don't expect there will be millions of players to rank!
  99.         IF Score(i) < Score(j) THEN SWAP Player$(i), Player$(j): SWAP Score(i), Score(j)
  100.     NEXT
  101.  
  102. OPEN "highscore.txt" FOR OUTPUT AS #1 'replace the old highscore file.
  103. FOR i = 1 TO players
  104.     PRINT #1, Player$(i)
  105.     PRINT #1, Score(i)
  106. OPEN "highscore.txt" FOR BINARY AS #1
  107. s$ = SPACE$(LOF(1))
  108. GET #1, 1, s$ 'get that information into a single large string
  109.  
  110.  
  111.  
  112. '****************************************************************
  113. '**
  114. '**  NEXT COMMAND IS STRESSED FOR EMPHASIS!  READ IT!!!!
  115. '**
  116. '*****************************************************************
  117.  
  118. Send Client, "[GAME PUT]highscore.txt" + CHR$(0) + s$ 'NOTICE THE SEPARATOR BETWEEN OUR COMMAND AND THE FILE CONTENTS
  119. 'WITHOUT THAT SEPARATOR (CHR$(0)), YOU WILL GET ERRORS AND NOT SAVE YOUR FILE.
  120.  
  121. '****************************************************************
  122. '**
  123. '**  PREVIOUS COMMAND IS STRESSED FOR EMPHASIS!  READ IT!!!!
  124. '**
  125. '*****************************************************************
  126.  
  127. PRINT Verify$
  128. PRINT "PLAYER SCORELIST"
  129. FOR i = 1 TO players 'just dump the player scores to the screen.
  130.     'I'm not looking for pretty at this point, just trying to highlight the functionality.
  131.     PRINT i; ") "; Player$(i), Score(i)
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. 'SERVER CODE BELOW
  140.  
  141.  
  142.  
  143. FUNCTION ConnectAsClient (Port$, IP$)
  144.     IF Verbose THEN PRINT "Connecting to Host as Client";
  145.     DO
  146.         count = count + 1
  147.         temp = _OPENCLIENT("TCP/IP:" + Port$ + ":" + IP$) 'attempt to join as client
  148.         _LIMIT 10
  149.         IF Verbose THEN PRINT ".";
  150.     LOOP UNTIL temp <> 0 OR count > 100
  151.     IF Verbose THEN PRINT
  152.     IF count > 50 THEN
  153.         IF Verbose THEN PRINT "Cannot connect to Host.  Terminating program."
  154.         END
  155.     END IF
  156.     IF Verbose THEN PRINT "Client Connected Successfully."
  157.     ConnectAsClient = temp
  158.  
  159. SUB Send (Who, What$)
  160.     IF Client = 0 OR What$ = "" THEN EXIT SUB
  161.     out$ = CHR$(2) 'an initial byte to say, "We're sending data."
  162.     out$ = out$ + _MK$(_INTEGER64, LEN(What$) + 8) '8 bytes to store the length of the data we're sending.
  163.     out$ = out$ + What$
  164.     PUT Client, , out$
  165.  
  166. SUB Receive (Who, What$)
  167.     STATIC In AS STRING
  168.     IF Client = 0 THEN EXIT SUB
  169.     IF In = "" THEN
  170.         GET Client, , B
  171.     ELSE
  172.         B = ASC(In)
  173.         r$ = r$ + In
  174.         In = "" 'Is there a message waiting for us, after we processed one message?
  175.     END IF
  176.     IF B = 2 THEN
  177.         DO
  178.             GET Client, , a$
  179.             IF a$ <> "" THEN r$ = r$ + a$
  180.             IF LEN(r$) > 8 THEN length = _CV(_INTEGER64, LEFT$(r$, 8))
  181.             _LIMIT 10
  182.         LOOP UNTIL LEN(r$) >= length AND length <> 0
  183.         What$ = MID$(r$, 9) '8 bytes for the length
  184.         In = MID$(r$, length + 1)
  185.     END IF
  186.  
  187. FUNCTION Verify$
  188.     DO
  189.         Receive Client, OK$ 'Get the confirmation message.
  190.         _LIMIT 10 'Use low CPU while waiting.  No need for a high number here... Be patient and let the server have time to respond.  Checking 10 times a second is more than enough to get an [OK] or [ERROR] message.
  191.     LOOP UNTIL OK$ <> ""
  192.     Verify$ = OK$
  193.  

My first game to take advantage of my little Open Game Server (topic here: https://www.qb64.org/forum/index.php?topic=1920.0).  If this works as it should for everyone, it'll highlight the process which people could follow to link their own games into the game server. 

All I can say at this point is to test it out and see if the thing works for you like it should, or not.  The first time you run it, you'll need to register a new account.  From them on, just log into your existing account.

Play the game -- it's quite complex, but I imagine you guys can sort it out without needing a ton of instructions -- and see who can get the highest score!  ;D

« Last Edit: November 28, 2019, 05:17:03 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Click It!
« Reply #1 on: November 27, 2019, 09:27:07 am »
This might be tangential, but that is interesting way to get clear of a click, except stuck with mouse down point but fine for most uses.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Click It!
« Reply #2 on: November 27, 2019, 09:32:15 am »
It’s how I generally get a lazy “click”.  Only when the mouse was up, and we push it down, does it count as a “click”.  Of course, we can hold it forever, and it won’t change anything or register any hold events, but it works excellent for getting single click events.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Click It!
« Reply #3 on: November 27, 2019, 09:35:34 am »
And, I know there’s not much game to this “game”.  The main purpose here is to show folks how they can connect to my server and use it for their own games, if they don’t have a static ip, open ports, or a space PC to run 24/7 hosting one.  ;)



Looking at the data file where a few people have played already, it seems as if the file is getting corrupted with bad data.  I’ll need to do some double checking to see what/where the glitch is occurring.  Passing 3-4 records seems fine.  More than that and things get buggy internally. 

Almost there, but not quite 100% yet.  :(
« Last Edit: November 27, 2019, 09:43:59 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Click It!
« Reply #4 on: November 28, 2019, 05:07:36 am »
Post above has been replaced with a new version of Click It!

I completely redid the server/client communication protocol, making things much simpler and much more efficient on both ends.  (I think there was about 50 lines of code which got shortened over all.)

The file corruption with the high score lists has been corrected as well.  You guys are welcome to try it out once more, but I think things are finally working as intended with this little pet server project.
« Last Edit: November 28, 2019, 05:18:32 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Click It!
« Reply #5 on: November 28, 2019, 12:09:16 pm »
Wow, Lots faster and more streamlined! nice.

Arg in second place now! have to click more!

back in first! :D
« Last Edit: November 28, 2019, 12:46:40 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!