Code: Select all
;
; RConWin
;
EnableExplicit
#SERVERDATA_AUTH = 3
#SERVERDATA_AUTH_RESPONSE = 2
#SERVERDATA_EXECCOMMAND = 2
#SERVERDATA_RESPONSE_VALUE = 0
Structure RCONPacketHeaderStructure
Size.l
ID.l
Type.l
EndStructure
Procedure.i RConSend(Con, ID.l, Type.l, Str1$, Str2$="")
Protected Result.i, PacketSize.l, *Buffer.RCONPacketHeaderStructure
PacketSize = SizeOf(RCONPacketHeaderStructure) + StringByteLength(Str1$, #PB_Ascii) + 1 + StringByteLength(Str2$, #PB_Ascii) + 1 ; + 1s for the terminating 0s
*Buffer = AllocateMemory(PacketSize)
If *Buffer
*Buffer\Size = PacketSize - SizeOf(Long)
*Buffer\ID = ID
*Buffer\Type = Type
PokeS(*Buffer + SizeOf(RCONPacketHeaderStructure), Str1$, -1, #PB_Ascii)
PokeS(*Buffer + SizeOf(RCONPacketHeaderStructure) + StringByteLength(Str1$, #PB_Ascii) + 1, Str2$, -1, #PB_Ascii) ; + 1 for the terminating 0 of Str1$
Result = SendNetworkData(Con, *Buffer, PacketSize)
FreeMemory(*Buffer)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.i RConReceive(Con, *ID, *CommandResponse, *Str1, *Str2, MaxWait)
Protected Result.i, Answer.i, BuffPtr.i, Received.i, Length.i, *Buffer.RCONPacketHeaderStructure
*Buffer = AllocateMemory(8192)
If *Buffer
Repeat
Select NetworkClientEvent(Con)
Case #PB_NetworkEvent_None
Delay(10)
MaxWait - 10
Case #PB_NetworkEvent_Data
Length = ReceiveNetworkData(Con, *Buffer + BuffPtr, 8192 - BuffPtr)
If Length
Received + Length
If Result = 0 And Length > 3
Result = *Buffer\Size
EndIf
If Received >= Result + 4
PokeL(*ID, *Buffer\ID)
PokeL(*CommandResponse, *Buffer\Type)
PokeS(*Str1, PeekS(*Buffer + 12, -1, #PB_Ascii), -1, #PB_Ascii)
PokeS(*Str2, PeekS(*Buffer + 12 + StringByteLength(PeekS(*Buffer + 12), #PB_Ascii) + 1), -1, #PB_Ascii)
Answer = #True
EndIf
BuffPtr + Length
EndIf
Case #PB_NetworkEvent_Disconnect
Break
EndSelect
Until MaxWait <= 0 Or Answer
FreeMemory(*Buffer)
If MaxWait < 0
MessageRequester("Error", "Receive timeout!")
Result = 0
EndIf
If Not Answer
Result = 0
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure RConProcessResponse(Con, OurID, CommandExpectedAnswer, EditGadgetNo)
Protected Result.i, ID.l, CommandResponse.l, *Str1, *Str2
*Str1 = AllocateMemory(4096)
If *Str1
*Str2 = AllocateMemory(4096)
If *Str2
While RConReceive(Con, @ID, @CommandResponse, *Str1, *Str2, 1000) > 0
If CommandResponse = CommandExpectedAnswer
Select CommandResponse
Case #SERVERDATA_AUTH_RESPONSE
If ID = OurID
Result = 1
ElseIf ID = -1
AddGadgetItem(EditGadgetNo, -1, "Password refused")
Else
AddGadgetItem(EditGadgetNo, -1, "Bad Auth Response ID: " + Str(ID))
EndIf
Case #SERVERDATA_RESPONSE_VALUE
AddGadgetItem(EditGadgetNo, -1, PeekS(*Str1, -1, #PB_Ascii))
Result = 2
Default
AddGadgetItem(EditGadgetNo, -1, "Unexpected command response: " + Str(CommandResponse))
EndSelect
Break
EndIf
Wend
FreeMemory(*Str2)
EndIf
FreeMemory(*Str1)
EndIf
ProcedureReturn Result
EndProcedure
Procedure Send(Server$, Port, OurID, Passwd$, Command$, EditGadgetNo)
Protected Con.i
Con = OpenNetworkConnection(Server$, Port, #PB_Network_TCP)
If Con
If RconSend(Con, OurID, #SERVERDATA_AUTH, Passwd$, "")
If RConProcessResponse(Con, OurID, #SERVERDATA_AUTH_RESPONSE, EditGadgetNo) = 1
If RConSend(Con, OurID, #SERVERDATA_EXECCOMMAND, Command$, "")
If RConProcessResponse(Con, OurID, #SERVERDATA_RESPONSE_VALUE, EditGadgetNo) <> 2
MessageRequester("Error", "No answer received For: " + Command$)
EndIf
Else
MessageRequester("Error", "Was Not possible To send: " + Command$)
EndIf
Else
MessageRequester("Error", "Authentication failed")
EndIf
Else
MessageRequester("Error", "Send failed")
EndIf
CloseNetworkConnection(Con)
Else
MessageRequester("Error", "Was Not able To establish a connection To " + Server$ + " at port " + Str(Port))
EndIf
EndProcedure
Define EventID.i
If InitNetwork()
If OpenWindow(0, 0, 0, 400, 440, "RConWin V1.10 by Infratec", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
TextGadget(0, 10, 10, 60, 20, "Server")
StringGadget(1, 80, 10, 100, 20, "127.0.0.1")
TextGadget(2, 200, 10, 60, 20, "Port")
StringGadget(3, 290, 10, 100, 20, "27015", #PB_String_Numeric)
TextGadget(4, 10, 30, 60, 20, "Password")
StringGadget(5, 80, 30, 100, 20, "", #PB_String_Password)
TextGadget(6, 200, 30, 60, 20, "ID")
StringGadget(7, 290, 30, 100, 20, "0", #PB_String_Numeric)
TextGadget(8, 10, 70, 60, 20, "Command")
StringGadget(9, 80, 70, 310, 20, "")
ButtonGadget(100, 10, 100, 380, 20, "Send")
EditorGadget(200, 10, 130, 380, 300, #PB_Editor_ReadOnly)
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
Select EventGadget()
Case 100
ClearGadgetItems(200)
;Send(Server$, Port, OurID, Passwd$, Command$, EditGadgetNo)
Send(GetGadgetText(1), Val(GetGadgetText(3)), Val(GetGadgetText(7)), GetGadgetText(5), GetGadgetText(9), 200)
EndSelect
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
Else
MessageRequester("Error", "Was not able to initialize the network!")
EndIf