Code archives/Networking/TCPIP 3D game example
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
A simple network game example. limited to 10.000 Connections. i made this as small as i Cold on 8 hours coding. warinig will code will crash if a client disconnect. this is only an example of how to code. and make silky smoth games with tcp/ip. | |||||
; Example blitz3d tcpip game. ; Written by wings on blitz forum wings@tiberion.eu ; Global server Global player Global player_guid ; player clident global indentifyer. Global player_guid_counter ; Here we create new ids Global client_debug_network ; A millisecond counter for debuging Global link ; This is player link. accaly i store session in this. i prefare name link. ;Data base for players Type player_type Field name$ Field player_guid Field x#,y#,z#,rot#,status Field mesh Field link End Type ;Try to Start the server. if port 7001 is not available game goes into client mode. Server = CreateTCPServer (7001) ; if this fails game will go on as a client Global rec_bank=CreateBank(512) ; A common datablock. used to store data from client Global send_bank=CreateBank(512) ; A common datablock. used to store data that is sent to clients. ;Setup Graphics mode & camera envornoment Graphics3D 800,600 SetBuffer BackBuffer() camera=CreateCamera() CameraViewport camera,0,0,800,600 CameraRange camera,1,100 CameraFogRange camera,2,100 CameraFogMode camera,True CameraFogColor camera,150,200,255 CameraClsColor camera,150,200,255 PositionEntity camera,0,10,-10 TurnEntity camera,30,0,0 light=CreateLight() ;Create a grass texture 64*64 with 1 flag and that is color. one can also use loadtexture grass=CreateTexture(64,64,1) SetBuffer TextureBuffer(grass) ClsColor 22,100,22 Cls For i=0 To 256 Color 0+Rnd(10),50+Rnd(155),0+Rnd(10) Plot Rnd(64),Rnd(64) Next SetBuffer BackBuffer() ScaleTexture grass,3,3 Color 255,255,255 ClsColor 0,0,0 ;Create the grass entity as a endless plane plane=CreatePlane() EntityTexture plane,grass ;Create player mesh player=CreateCube() PositionEntity player,5,1,5 ;The big main. mixed server & client in same code. While Not KeyHit(1) server_function() player_controlls() update_player_positions() UpdateWorld() RenderWorld() draw_status_texts() client_networking() Flip Wend ;Draw varius status text on screen. and some help. Function draw_status_texts() Text 0,0,"Blitz3d TCPIP Example" If server Text 0,10,"player_guid_counter="+player_guid_counter Else If link=0 Then Text 0,10,"Press F1 for connect to server" Text 0,30,"client_debug_network="+client_debug_network End If If link=0 Text 0,20,"Not Connected" Else Text 0,20,"Connected" End If End Function ; Here we place all server handling functions. like accept new streams and send recive data from clients. Function server_function() ;Only run this if its the server. If server ;TCP/IP stream check for new one. server_check() ; ;TCP/IP Handling of streams. like sending reciving. server_handle_player() ;update client position of server object. this makes the server also move at clients no neet to send our self to server. ;) p.player_type = First player_type p\x#=EntityX#(player) p\y#=EntityY#(player) p\z#=EntityZ#(player) p\rot#=EntityYaw(player) End If End Function ;Here we handle all player controlls. left/right forward/backward even commands for connect to server. Function player_controlls() If KeyHit(59) And server=False Then connect_to_server() ; Connect to server F1 If KeyDown(17) ; Mover forward "w" MoveEntity player,0,0,0.05 End If If KeyDown(31) ; Move backward "s" MoveEntity player,0,0,-0.05 End If If KeyDown(30) ; Turn Left "a" TurnEntity player,0,1,0 End If If KeyDown(32) ; Turn right "d" TurnEntity player,0,-1,0 End If End Function ;Updates the meshes from data structure. that been loaded from network last. this makes players move on each other screens. and rotates Function update_player_positions() ;Update player positions For p.player_type=Each player_type If p\mesh<>player PositionEntity p\mesh,p\x#,p\y#,p\z# RotateEntity p\mesh,EntityPitch(p\mesh),p\rot#,EntityRoll(p\mesh) End If Next End Function ;Server needs to check for new players connection setup. it alls hapends here. Function server_check() ;This code counts the registred players i=0 For p.player_type = Each player_type i=i+1 Next ;If there is no one register even the server is not register. then this code creates the first player with the Guid 0 The first one :) If i=0 p.player_type= New player_type p\x#=EntityX#(player) p\y#=EntityY#(player) p\z#=EntityZ#(player) p\player_guid=0 p\mesh=player End If ;Check for new streams connected. and if detect a new stream create a new player give it a guid. stream=AcceptTCPStream(Server) If stream Cls Print "A new stream connected !" Delay 2000 ;Create a new player for stream p.player_type= New player_type p\link = stream p\mesh=CreateCube() player_guid_counter=player_guid_counter+1 p\player_guid = player_guid_counter ; The stream has now a global indentifyer. now that is nice. End If ;Security code If player_guid_counter>10000 Then RuntimeError ("Some fool is hacking our little game client or you been playing far to long.") ; Be sure to put in this kind of bugs. lamo lama End Function ;Player networking handling. here player clients get there data from server and sending it curent position. Function client_networking() ;Only run this code if a datalink has been establish If link ms=MilliSecs() ;Send client data to server. evert frame this is done ;) PokeInt send_bank,0,1000 ; CLient cord package. PokeFloat send_bank,4,EntityX#(player) PokeFloat send_bank,4+8,EntityY#(player) PokeFloat send_bank,4+16,EntityZ#(player) PokeFloat send_bank,4+24,EntityYaw#(player) WriteBytes send_bank,link,0,512 ; Write it all to stream. Repeat again=False If ReadAvail(link)>=512 ; Ya we got somthing to read. again=True bytes=ReadBytes(rec_bank,link,0,512) If bytes<512 Then RuntimeError "The client stream broke sir.." ; Lamo was here Select PeekInt(rec_bank,0) Case 1001 ; Found a client cordinate package. guid=PeekInt(rec_bank,4) ; global id newplayer=True For p2.player_type = Each player_type If guid=p2\player_guid newplayer = False ; Found the player.. now store data p2\x#=PeekFloat#(rec_bank,8) p2\y#=PeekFloat#(rec_bank,16) p2\z#=PeekFloat#(rec_bank,24) p2\rot#=PeekFloat#(rec_bank,32) End If Next If newplayer=True p2.player_type = New player_type p2\mesh=CreateCube() EntityColor p2\mesh,Rnd(255),Rnd(255),Rnd(255) p2\player_guid=guid p2\x#=PeekFloat#(rec_bank,8) p2\y#=PeekFloat#(rec_bank,16) p2\z#=PeekFloat#(rec_bank,24) p2\rot#=PeekFloat#(rec_bank,32) End If End Select End If Until ReadAvail(link)<512 client_debug_network=MilliSecs()-ms End If ;End of whole network block End Function ;This functions takes care of all player network data recive and send. Function server_handle_player() For p.player_type= Each player_type If p\player_guid<>0 If Eof(p\link) Then RuntimeError "A client quitet.. server crash ! Best regards Lamo coder" ;Realy put in some client kill & cleanup code here ;D Repeat If ReadAvail(p\link)>=512 ; Yes only 512 is a magic thing. bytes=ReadBytes(rec_bank,p\link,0,512) If bytes<>512 Then RuntimeError ("Awsome client dint send 512.. wat to to Regards Lamo coder"); Yes we shold kick and ban this hacker or poor internet connection for a user. Select PeekInt(rec_bank,0) ; Reads the first byte and we go from there.. Case 1000 ; Defaul x,y,z, data player cordinate packet recived. ;Read the data from packet into the database. X,Y,Z and Rotation (yaw) p\x#=PeekFloat(rec_bank,4) p\y#=PeekFloat(rec_bank,4+8) p\z#=PeekFloat(rec_bank,4+16) p\rot#=PeekFloat(rec_bank,4+24) ;Well we shold make a payback to client as thanks for player cords ;) For p2.player_type= Each player_type If p2.player_type<> p.player_type;Every one except it self. PokeInt rec_bank,0,1001 ; A client cordinate package. Note i call this one 1001.. a reply from server clients cords. its verry important PokeInt rec_bank,4,p2\player_guid PokeFloat rec_bank,8,p2\x# ;X position PokeFloat rec_bank,16,p2\y# ;Y position PokeFloat rec_bank,24,p2\z# ;Z Position PokeFloat rec_bank,32,p2\rot# ; Rotation WriteBytes rec_bank,p\link,0,512 ; Send the data block End If Next ; End of all other clients cords to the client End Select End If Until ReadAvail(p\link)<512 ; we need to read all packets before continue to clear tcp buffer. End If Next End Function ;Simple try to connect to server. Function connect_to_server() Cls Print "Trying to connect to server" Print "Open stream" link=OpenTCPStream("localhost",7001) Print link If Not link Then RuntimeError "Failed to connect to server." Print "Connection success" Flip Delay 2000 End Function |
Comments
| ||
Thans for this. It's a nice bit of work. If it is possible, could you at some time include a detailed explanation of what each section does. I'm at a loss for the correct usage of TCP and UDP Thanks though |
| ||
Wings, thank you! please tell why 512? is this MSS? % 512 + 40 = 552 MTU? |
| ||
how do I connect to server? |
Code Archives Forum