AppTitle "StuntMoto server"
Graphics 800,600,32,2
SeedRnd MilliSecs()
;Consts
Const Port=53006
;Types
Type Player
Field Name$
Field X#
Field Y#
Field Z#
Field Pitch#
Field Yaw#
Field Roll#
Field RearWheelSpeed#
Field FrontWheelSpeed#
Field TurnVol#
Field Connection
Field IP$
End Type
;Globals
Global Bank=CreateBank(512)
Global Server=CreateTCPServer(Port)
If Not Server Then RuntimeError "Could not create server at port " + Port
Print "Server started."
Repeat
;Check for incoming connections
NewConnection = AcceptTCPStream(Server)
If NewConnection Then
p.Player = New Player
p\Connection = NewConnection
p\Name$ = ""
p\RearWheelSpeed = 0.0
p\FrontWheelSpeed = 0.0
p\TurnVol# = 0.0
p\IP$ = DottedIP$(TCPStreamIP(p\Connection))
Print p\IP$ + " connected!"
EndIf
;Loop players
For p.Player = Each Player
;Disconnect
If Eof(p\Connection) Or (Not p\Connection) Then
Print p\Ip$ + " disconnected!"
;Broadcast players
For p2.Player = Each Player
If p <> p2 Then
WriteLine p2\Connection,"2"+p\Name$
EndIf
Next
;Delete player
Delete p.Player
Else
;Read msg
If ReadAvail(p\Connection)>0 Then
ReceivedMsg$ = Chr$(ReadByte(p\Connection))
If Left$(ReceivedMsg$,1) = "1" Then
ReceivedMsg$=ReadLine$(p\Connection)
;Received name
p\Name$ = ReceivedMsg$
While Not Freename(p,p\Name$)
p\Name$ = "player"+Rand(0,9)+Rand(0,9)+Rand(0,9)+Rand(0,9)
Wend
Print "Name received: " + p\Name$
;Broadcast new player
For p2.Player = Each Player
If p <> p2 Then
WriteLine p2\Connection,"1"+p\Name$
EndIf
Next
EndIf
;Chat
If Left$(ReceivedMsg$,1) = "3" Then
ReceivedMsg$ = ReadLine$(p\Connection)
;Broadcast chat
For p2.Player = Each Player
If Not Eof(p2\Connection) Then WriteLine p2\Connection,"3"+p\Name$+": "+ReceivedMsg$
Next
EndIf
;Update pos
If Left$(ReceivedMsg$,1) = "4" Then
ReadBytes Bank,p\Connection,2,36
PokeByte Bank,0,Asc("4")
PokeByte Bank,1,38+Len(p\Name$)
p\X# = PeekFloat(Bank,2)
p\Y# = PeekFloat(Bank,6)
p\Z# = PeekFloat(Bank,10)
p\Pitch# = PeekFloat(Bank,14)
p\Yaw# = PeekFloat(Bank,18)
p\Roll# = PeekFloat(Bank,22)
p\RearWheelSpeed# = PeekFloat(Bank,26)
p\FrontWheelSpeed# = PeekFloat(Bank,30)
p\TurnVol# = PeekFloat(Bank,34)
PokeString(p\Name$,Bank,38)
;Print "Received "+p\X#+","+p\Y#+","+p\Z#
;Broadcast
For p2.Player = Each Player
If Not Eof(p2\Connection) Then
If p <> p2 Then
WriteBytes Bank,p2\Connection,0,38+Len(p\Name$)
EndIf
EndIf
Next
EndIf
EndIf
EndIf
Next
Until KeyHit(1)
Function Freename(p4.Player,TestName$)
For p3.Player = Each Player
If (p3\Name$ = TestName$) And (p3<>p4) Then Return False
Next
Return True
End Function
Function StringToBank(FromString$,ToBank,Count)
For t=0 To Count-1
PokeByte ToBank,t,Asc(Mid$(FromString,t+1,1))
Next
End Function
Function PokeString(FromString$,ToBank,Offset)
For t=0 To Len(FromString$)-1
PokeByte ToBank,t+OffSet,Asc(Mid$(FromString$,t+1,1))
Next
End Function
Function PeekString$(FromBank,OffSet,Count)
rString$=""
For t=Offset To Offset+Count-1
rString$ = rString$ + Chr$(PeekByte(FromBank,t))
Next
Return rString$
End Function