Jedenfalls ist das Spiel extrem primitiv. Nur 4 Variablen. Das kann man praktisch nicht alleine Spielen...
Der Witz kommt eher wenn man es gegen andere spielt.
Naja, also nichts wirklich ernsthaftes. Eher als Codebeispiel für die Netzwerkfunktionen gemacht.
Code: Alles auswählen
; ein "psychologisches" Spiel(chen) von Dostej
; kann von 2-9 Spielern im LAN (oder übers Netz) gespielt werden
;{- Konstanten
; Window Constants
Enumeration
#WND_Join_Game
#WND_SERVERB
#WND_CON
#WND_Victim
#WND_WAITSTART
EndEnumeration
; Gadget Constants
Enumeration
#WND_SERVERB_TXT_IP
#WND_SERVERB_Port
#WND_SERVERB_STR_IP
#WND_SERVERB_STR_Port
#WND_SERVERB_BTN_Abbruch
#WND_SERVERB_BTN_OK
#CON_IMG
#CON_LICON
#CON_TXT_AktionsPunkte
#CON_BTN_Prod
#CON_BTN_Luftwaffe
#CON_BTN_Heer
#CON_BTN_Diplomatie
#CON_BTN_Land
#CON_BTN_Fertig
#CON_IMG_Eigenfarbe
#CON_TXT_Runde
#CON_BTN_Spionage
#CON_BTN_Angriff
#WND_WAITSTART_PBAR
#WND_WAITSTART_TXT_SpielerBisher
#WND_WAITSTART_BTN_Start
#WND_WAITSTART_BTN_Abbruch
#WND_Victim_IMG_0
#WND_Victim_TXT_0
#WND_Victim_IMG_1
#WND_Victim_TXT_1
#WND_Victim_IMG_2
#WND_Victim_TXT_2
#WND_Victim_IMG_3
#WND_Victim_TXT_3
#WND_Victim_IMG_4
#WND_Victim_TXT_4
#WND_Victim_IMG_5
#WND_Victim_TXT_5
#WND_Victim_IMG_6
#WND_Victim_TXT_6
#WND_Victim_IMG_7
#WND_Victim_TXT_7
#WND_Victim_IMG_8
#WND_Victim_TXT_8
#WND_Victim_BTN_Abbruch
#WND_Join_Game_LICON
#WND_Join_Game_BTN_OK
#WND_Join_Game_BTN_Abbruch
EndEnumeration
; IMages
Enumeration
#IMG_Info
#IMG_Farbe
#IMG_Victim_0
#IMG_Victim_1
#IMG_Victim_2
#IMG_Victim_3
#IMG_Victim_4
#IMG_Victim_5
#IMG_Victim_6
#IMG_Victim_7
#IMG_Victim_8
EndEnumeration
;Fonts
Enumeration
#FNT_Titel
#FNT_Zwischen
#FNT_Standard
EndEnumeration
#MAX_PREFERRED_LENGTH = -1
#SV_TYPE_ALL = $FFFFFFFF
#NERR_SUCCESS = 0
#ERROR_MORE_DATA = 234
#MainWindow = 100
#MMTB = 200
#MAX_CLIENTS = 8
;}
;{- Strukturen und Vars
; die Systemdaten für das Netzspiel
Structure HOSTENT
h_name.l
h_aliases.l
h_addrtype.w
h_length.w
h_addr_list.l
EndStructure
Structure SERVER_INFO_101
dwPlatformId.l
lpszServerName.l
dwVersionMajor.l
dwVersionMinor.l
dwType.l
lpszComment.l
EndStructure
Structure LAN_RESULT
Name.s
IP_Name.s
Aktiv_Server.l ; 1, wenn dort ein aktiver Server gefunden werden konnte, dann sind auch die weiteren Daten belegt
Spiel_Name.s
Spieler_bisher.l
EndStructure
NewList LAN_Client.LAN_RESULT()
Global Spionage ; =1, wenn der Punkt für Spionage ausgegeben wurde
Global Runde_fertig.l ; = 1, wenn der Spieler die Daten gesendet hat
Global NetzwerkID ; beinhaltet die ID des Servers
Global Spieler_nr.l ; die Spielernummer im aktuellen Spiel
Global Port.l ; enthält den verwendeten Port. Standardmässig ist das 1000
; Die Spieldaten
Structure ply
Aktiv.l ; =1, wenn Spieler aktiv
Runde.l ; Rundennummer
Aktionspunkte.l ; die restlichen Aktionspunkte für diese Runde
Produktion.l ; Ergibt die Aktionspunkte
Luftwaffe.l ; Anzahl der Flieger
Heer.l ; Anzahl der Truppen
Land.l ; Landgrösse
Victim.l ; = -1, wenn niemand angegriffen werden soll, ansonsten die Spielernummer
Victim_davor.l ; speichert den Ziel der letzten Runde
EndStructure
Dim player.ply(#MAX_CLIENTS)
Dim col.l(#MAX_CLIENTS)
col(0) = $00FFFF
col(1) = $0000FF
col(2) = $00FF00
col(3) = $FF0000
col(4) = $FF00FF
col(5) = $0080FF
col(6) = $FFFF00
col(7) = $FFFFFF
col(8) = $800080
Global Ownpath.s
CompilerIf #jaPBe_IsExecute
Ownpath = Space(1000)
GetModuleFileName_(0,@Ownpath,1000)
Ownpath = GetPathPart(Ownpath)
CompilerElse
Ownpath = "C:\PureBasic\projects\Entscheidungen\"
CompilerEndIf
;}
;{- Bilder
CreateImage(#IMG_Info, 500, 510)
CreateImage(#IMG_Farbe, 30, 30)
CreateImage(#IMG_Victim_0, 30, 30)
CreateImage(#IMG_Victim_1, 30, 30)
CreateImage(#IMG_Victim_2, 30, 30)
CreateImage(#IMG_Victim_3, 30, 30)
CreateImage(#IMG_Victim_4, 30, 30)
CreateImage(#IMG_Victim_5, 30, 30)
CreateImage(#IMG_Victim_6, 30, 30)
CreateImage(#IMG_Victim_7, 30, 30)
CreateImage(#IMG_Victim_8, 30, 30)
For x = #IMG_Victim_0 To #IMG_Victim_8 ; die Bilder kolorieren
UseImage(x)
StartDrawing(ImageOutput())
Box(0, 0, 30, 30, col(x-#IMG_Victim_0))
StopDrawing()
Next
;}
;{- Sonstiges
LoadFont(#FNT_Titel, "Arial", 24, #PB_Font_Bold | #PB_Font_Italic)
LoadFont(#FNT_Zwischen, "Arial", 16, #PB_Font_Bold)
LoadFont(#FNT_Standard, "Arial", 11)
;}
;{- Initialisieren
If InitSprite() And InitKeyboard() And InitNetwork() = 0
MessageRequester("Error", "Cant initialize Core")
End
EndIf
;}
;{- Proceduren
; Core
Procedure ArraySize(*Array)
ProcedureReturn PeekL(*Array-8)
EndProcedure
; Server anmeldung
Procedure.l Input_Server_Connections()
; Gibt 1 zurück, wenn ok, ansonsten -1
back.l = -1
If OpenWindow(#WND_SERVERB, 270, 248, 295, 110, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Verbindungsdaten zum Server einegben", UseWindow(#WND_CON))
If CreateGadgetList(WindowID())
TextGadget(#WND_SERVERB_TXT_IP, 10, 10, 120, 20, "IP Adresse", #PB_Text_Border)
TextGadget(#WND_SERVERB_Port, 10, 40, 120, 20, "Verwendeter Port", #PB_Text_Border)
IPAddressGadget(#WND_SERVERB_STR_IP, 140, 10, 150, 20)
StringGadget(#WND_SERVERB_STR_Port, 140, 40, 70, 20, "1000", #PB_String_Numeric)
ButtonGadget(#WND_SERVERB_BTN_Abbruch, 40, 80, 90, 20, "Abbruch")
ButtonGadget(#WND_SERVERB_BTN_OK, 140, 80, 90, 20, "OK")
SetGadgetState(#WND_SERVERB_STR_IP, MakeIPAddress(127, 0, 0, 1))
Repeat ; Start of the event loop
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadgetID() ; Is it a gadget event?
EventType = EventType() ; The event type
If Event = #PB_EventGadget
If GadgetID = #WND_SERVERB_BTN_Abbruch
Event = #PB_Event_CloseWindow
back = -1
ElseIf GadgetID = #WND_SERVERB_BTN_OK
Event = #PB_Event_CloseWindow
back = 1
EndIf
EndIf
Until Event = #PB_Event_CloseWindow ; End of the event loop
Event = 0
AddElement(LAN_Client())
LAN_Client()\IP_Name = IPString(GetGadgetState(#WND_SERVERB_STR_IP))
Debug "ip: " + LAN_Client()\IP_Name
Port = Val(GetGadgetText(#WND_SERVERB_STR_Port))
CloseWindow(#WND_SERVERB)
; Versuche die Verbindung zum Server herzustellen und anzumelden
; NetzwerkID = LAN_Client()\Aktiv_Server
; SpielName.s = LAN_Client()\Spiel_Name
EndIf
EndIf
ProcedureReturn back
EndProcedure
Procedure.s GetIPbyName (NameIP.s)
TheIPAdress.s
pHostinfo = gethostbyname_(NameIP)
If pHostinfo = 0
TheIPAdress = "Unable to resolve domain name"
Else
CopyMemory (pHostinfo, hostinfo.HOSTENT, SizeOf(HOSTENT))
If hostinfo\h_addrtype <> #AF_INET
MessageRequester("Info","A non-IP address was returned",0)
Else
While PeekL(hostinfo\h_addr_list+AdressNumber*4)
ipAddress = PeekL(hostinfo\h_addr_list+AdressNumber*4)
TheIPAdress = StrU(PeekB(ipAddress),0)+"."+StrU(PeekB(ipAddress+1),0)+"."+StrU(PeekB(ipAddress+2),0)+"."+StrU(PeekB(ipAddress+3),0)
AdressNumber+1
Wend
EndIf
EndIf
ProcedureReturn TheIPAdress
EndProcedure
Procedure GetLANList()
IPResult.s
se101.SERVER_INFO_101
nStructSize = SizeOf(SERVER_INFO_101)
RetCode = NetServerEnum_(0, 101, @bufptr, #MAX_PREFERRED_LENGTH, @dwEntriesread, @dwTotalentries, #SV_TYPE_ALL, 0, @dwResumehandle)
If RetCode = #NERR_SUCCESS And RetCode <> #ERROR_MORE_DATA
For i = 0 To dwEntriesread - 1
CopyMemory( bufptr + (nStructSize * i),@se101, nStructSize)
Buffer.s=Space(512)
result=WideCharToMultiByte_(#CP_ACP, 0, se101\lpszServerName, 255, @Buffer.s, 512, 0, 0)
IPResult = GetIPbyName (Buffer)
AddElement(LAN_Client())
LAN_Client()\Name = Buffer
LAN_Client()\IP_Name = IPResult
Next
Else
MessageRequester("Info","Failed",0)
EndIf
NetApiBufferFree_(bufptr)
; SendMessage_(MMTextBox,$00B6,0,30)
EndProcedure
Procedure.l Open_WND_Join_Game()
; wählt ein Spiel aus und schliesst die offenen Verbindungen zu anderen Spielservern
; Gibt den Listindex des gewählten Lan-Spiels zurück, oder -1, wenn keines gewählt wurde
back.l = -1
If OpenWindow(#WND_Join_Game, 216, 0, 313, 399, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Join Game", UseWindow(#WND_CON))
If CreateGadgetList(WindowID())
;-
ListIconGadget(#WND_Join_Game_LICON, 10, 30, 290, 330, "Spiel Name", 200)
AddGadgetColumn(#WND_Join_Game_LICON, 2, "Spieler bisher", 85)
AddGadgetColumn(#WND_Join_Game_LICON, 3, "", 1)
ButtonGadget(#WND_Join_Game_BTN_OK, 230, 370, 70, 20, "OK")
ButtonGadget(#WND_Join_Game_BTN_Abbruch, 10, 370, 70, 20, "Abbruch")
; die Gadgets vorbereiten
ResetList(LAN_Client())
While NextElement(LAN_Client())
If LAN_Client()\Aktiv_Server
AddGadgetItem(#WND_Join_Game_LICON, -1, LAN_Client()\Name + " - " + LAN_Client()\Spiel_Name + Chr(10) + Str(LAN_Client()\Spieler_bisher) + Chr(10) + Str(ListIndex(LAN_Client())))
EndIf
Wend
; Aktionsschleife
Repeat
Event = WaitWindowEvent()
If Event = #PB_EventGadget
GadgetID = EventGadgetID()
If GadgetID = #WND_Join_Game_LICON
back = Val(GetGadgetItemText(#WND_Join_Game_LICON, GetGadgetState(#WND_Join_Game_LICON), 2)) ; den index auslesen
ElseIf GadgetID = #WND_Join_Game_BTN_OK
Event = #PB_EventCloseWindow
ElseIf GadgetID = #WND_Join_Game_BTN_Abbruch
back = -1
Event = #PB_EventCloseWindow
EndIf
EndIf
Until Event = #PB_EventCloseWindow
Event = 0 ; nur dieses Fenster schliessen
; die anderen offenen Serververbindungen schliessen
ResetList(LAN_Client())
While NextElement(LAN_Client())
If LAN_Client()\Aktiv_Server And ListIndex(LAN_Client()) <> back ; wenn server, aber nicht der ausgewählte
CloseNetworkConnection(LAN_Client()\Aktiv_Server)
EndIf
Wend
CloseWindow(#WND_Join_Game)
EndIf
EndIf
ProcedureReturn back
EndProcedure
Procedure.l Register_at_Server()
; registriert den Client am Server
t.l = 1
; Am Spiel anmelden
Msg.s = "1" ; Bitte um Anmeldung beim Spiel
SendNetworkData(NetzwerkID, @Msg, 1) ; anmeldung für Spiel schicken
Msg = " "
Debug "spielnr vor dem Bestätigungsstring " + Str(Spieler_nr)
Repeat ; warte auf die Anmeldebestätigung
If NetworkClientEvent(NetzwerkID) = 2
ReceiveNetworkData(NetzwerkID, @Msg, 3)
Msg = RTrim(Msg)
Debug "anmeldestring - bestätigung direkteingabe: " + Msg
Spieler_nr = Val(Right(Msg, 1))
LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
Debug "Spieler_Nr erhalten: " + Str(Spieler_nr)
EndIf
Delay(100) ; 10 Abfragen pro Sek langen
Until Spieler_nr > -1
If Spieler_nr = 9 ; Kein platz mehr
Spieler_nr = -1
t = -1
MessageRequester("Fehler", "Alle Plätze sind bereits besetzt")
EndIf
ProcedureReturn t
EndProcedure
; Spieldaten übers Netz
Procedure Send_Game_Data()
; schickt die Spieldaten an den Server
If NetzwerkID
SendNetworkData(NetzwerkID, @player(Spieler_nr), SizeOf(ply))
Debug "Spieldaten an Server gesendet"
Else
MessageRequester("Fehler", "Kein Spielserver bekannt")
EndIf
EndProcedure
Procedure Get_Net_Data()
; testet, ob Daten vom Server gekommen sind
EndProcedure
Procedure.l Receive_Game_Data()
; empfängt die Spieldaten vom Server
t.l = -1
If NetzwerkID
Repeat ; warten, bis die neuen Rundendaten vom Server da sind
If NetworkClientEvent(NetzwerkID) = 2
Debug "size array: " + Str(SizeOf(ply) * ArraySize(@player()))
Debug "structsize: " + Str(SizeOf(ply))
Debug " received: " + Str(ReceiveNetworkData(NetzwerkID, @player(), SizeOf(ply) * ArraySize(@player())))
t = 1
EndIf
Delay(100)
Until t > -1
; MessageRequester("Rundenbeginn", "Runde " + Str(player(Spieler_nr)\Runde) )
s.s = ""
For x = 0 To #MAX_CLIENTS
If player(x)\Aktiv
If player(x)\Victim_davor = Spieler_nr
s = s + Chr(13) + Chr(10) + "- Spieler " + Str(x)
EndIf
EndIf
Next
If s <> "" ; wenn Angriffe stattfanden
MessageRequester("Kriegsbricht", "Sie wurden angegriffen von:" + s)
EndIf
Runde_fertig = 0 ; nächste Runde
Spionage = 0 ; Spionage auf 0 gesetzt
DisableGadget(#CON_BTN_Spionage, 0)
Else
MessageRequester("Fehler", "Es läuft kein Spiel")
EndIf
ProcedureReturn back
EndProcedure
; Sonstiges
Procedure Refresh_Data()
; baut die Spieldaten neu auf
Debug "refresh Data"
SetGadgetText(#CON_TXT_AktionsPunkte, "Aktionspunkte: " + Str(player(Spieler_nr)\Aktionspunkte))
SetGadgetText(#CON_TXT_Runde, "Runde: " + Str(player(Spieler_nr)\Runde))
ClearGadgetItemList(#CON_LICON)
AddGadgetItem(#CON_LICON, -1, "Produktion" + Chr(10) + Str(player(Spieler_nr)\Produktion))
AddGadgetItem(#CON_LICON, -1, "Luftwaffe" + Chr(10) + Str(player(Spieler_nr)\Luftwaffe))
AddGadgetItem(#CON_LICON, -1, "Heer" + Chr(10) + Str(player(Spieler_nr)\Heer))
AddGadgetItem(#CON_LICON, -1, "Land" + Chr(10) + Str(player(Spieler_nr)\Land))
If player(Spieler_nr)\Victim > -1
AddGadgetItem(#CON_LICON, -1, "Angriff auf" + Chr(10) + "Spieler " + Str(player(Spieler_nr)\Victim))
EndIf
SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
UseImage(#IMG_Farbe)
StartDrawing(ImageOutput())
Box(0, 0, 30, 30, col(Spieler_nr))
StopDrawing()
SetGadgetState(#CON_IMG_Eigenfarbe, UseImage(#IMG_Farbe))
EndProcedure
Procedure Paint_Info()
; zeichnet das grosse img
UseImage(#IMG_Info)
StartDrawing(ImageOutput())
Box(0, 0, 500, 510, $C0C0C0)
DrawingMode(1)
If player(x)\Runde = 0 ; wenn noch nicht angefangen
;{ Grundlegende Infos anzeigen
cnt.l = 10
Locate(100, cnt)
DrawingFont(UseFont(#FNT_Titel))
DrawText("Entscheidung")
DrawingFont(UseFont(#FNT_Standard))
cnt + 55 : Locate(10, cnt)
DrawText("Das Spiel ist denkbar einfach, um nicht zu sagen primitiv")
cnt + 20 : Locate(10, cnt)
DrawText("Alleine zu spielen ist es gähnend langweilig. Denn das Spiel")
cnt + 20 : Locate(10, cnt)
DrawText("gewinnt seinen Reiz durch die Einschätzung des Gegners.")
cnt + 20 : Locate(10, cnt)
DrawText("(Besonders wenn man es mehrmals hintereinander spielt)")
cnt + 35 : Locate(10, cnt)
DrawingFont(UseFont(#FNT_Zwischen))
DrawText("Spielregeln")
DrawingFont(UseFont(#FNT_Standard))
cnt + 30 : Locate(10, cnt)
DrawText("Sie haben ein Land, mit Armee und Produktion. Das haben alle Spieler.")
cnt + 20 : Locate(10, cnt)
DrawText("Sie haben pro Runde so viele Aktionspunkte, wie sie Produktion haben.")
cnt + 20 : Locate(10, cnt)
DrawText("Pro Aktionpunkt können sie 1 Produktion, Armeeeinheit oder Land kaufen.")
cnt + 20 : Locate(10, cnt)
DrawText("Oder sich über die Spieldaten der anderen Spieler informieren (Spionage).")
cnt + 25 : Locate(10, cnt)
DrawText("Um ihre Armee zu unterhalten, benötigen sie je Einheit 1 Produktion.")
cnt + 20 : Locate(10, cnt)
DrawText("Die Grösse des Landes begrenzt die Anzahl der Produktion.")
cnt + 25 : Locate(10, cnt)
DrawText("Sie können andere Spieler mit ihrer Armee angreifen.")
cnt + 20 : Locate(10, cnt)
DrawText("Dabei zerstört die Luftwaffe die Produktion des Gegners")
cnt + 20 : Locate(10, cnt)
DrawText("und das Heer erbeutet evtl. Land vom Gegner.")
cnt + 30 : Locate(10, cnt)
DrawText("Der Spionagebericht zeigt die aktuellen Daten des Gegners an, bis auf den")
cnt + 20 : Locate(10, cnt)
DrawText("Kreigsbericht, der zeigt den Angriff der letzten Runde.")
cnt + 60 : Locate(10, cnt)
DrawText("Um das Spiel zu starten klicken sie mit der Maus.")
cnt + 20 : Locate(10, cnt)
DrawText("")
StopDrawing()
SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
Repeat
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
Until EventType() = #PB_EventType_LeftClick
;}
Else
;{ Der Spionagebericht
Debug "zeichne info"
For x = 0 To #MAX_CLIENTS ; das Infofeld zeichnen
If player(x)\Aktiv
Box(5, 10 + x * 55, 30, 30, col(x))
If Spionage
Locate(50, 15 + x * 55)
s.s = " Land: " + Str(player(x)\Land)
s = s + " Prod: " + Str(player(x)\Produktion)
s = s + " Luftwaffe: " + Str(player(x)\Luftwaffe)
s = s + " Heer: " + Str(player(x)\Heer)
If player(x)\Victim_davor <> -1
s = s + " Krieg Spl: " + Str(player(x)\Victim_davor)
Else
s = s + " ---"
EndIf
DrawText("Spieler " + Str(x) + s)
EndIf
EndIf
Next
StopDrawing()
SetGadgetState(#CON_IMG, UseImage(#IMG_Info))
;}
EndIf
EndProcedure
Procedure.l Choose_Victim()
; sucht ein Opfer für den Angriff aus
back.l = -1
If OpenWindow(#WND_Victim, 216, 0, 190, 410, #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "Wählen Sie ein Angriffsziel", UseWindow(#WND_CON))
If CreateGadgetList(WindowID())
For x = 0 To #MAX_CLIENTS
If player(x)\Aktiv And x <> Spieler_nr ;nicht sich selbst
ImageGadget(#WND_Victim_IMG_0 + x * 2, 10, 15 + x * 40, 30, 30, UseImage(#IMG_Victim_0 + x))
TextGadget(#WND_Victim_TXT_0 + x * 2, 60, 20 + x * 40, 120, 20, "Spieler " + Str(x), #PB_Text_Border)
EndIf
Next
ButtonGadget(#WND_Victim_BTN_Abbruch, 50, 380, 90, 20, "Abbruch")
Repeat ; Start of the event loop
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadgetID() ; Is it a gadget event?
EventType = EventType() ; The event type
;You can place code here, and use the result as parameters for the procedures
If Event = #PB_EventGadget
If GadgetID = #WND_Victim_BTN_Abbruch
Event = #PB_Event_CloseWindow
ElseIf GadgetID = #WND_Victim_IMG_0
back = 0
ElseIf GadgetID = #WND_Victim_IMG_1
back = 1
ElseIf GadgetID = #WND_Victim_IMG_2
back = 2
ElseIf GadgetID = #WND_Victim_IMG_3
back = 3
ElseIf GadgetID = #WND_Victim_IMG_4
back = 4
ElseIf GadgetID = #WND_Victim_IMG_5
back = 5
ElseIf GadgetID = #WND_Victim_IMG_6
back = 6
ElseIf GadgetID = #WND_Victim_IMG_7
back = 7
ElseIf GadgetID = #WND_Victim_IMG_8
back = 8
EndIf
EndIf
Until Event = #PB_Event_CloseWindow Or back <> -1 ; End of the event loop
Event = 0
CloseWindow(#WND_Victim)
EndIf
EndIf
ProcedureReturn back
EndProcedure
Procedure Open_Game_Win()
If OpenWindow(#WND_CON, 216, 0, 766, 531, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar , "Entscheidungen")
If CreateGadgetList(WindowID())
;{- Fenster aufbauen
ImageGadget(#CON_IMG, 10, 10, 500, 510, UseImage(#IMG_Info), #PB_Image_Border)
;-
ListIconGadget(#CON_LICON, 530, 10, 230, 160, "Land", 145)
AddGadgetColumn(#CON_LICON, 1, "Werte", 80)
TextGadget(#CON_TXT_AktionsPunkte, 530, 240, 230, 20, "")
ButtonGadget(#CON_BTN_Prod, 530, 270, 110, 30, "Produktion")
ButtonGadget(#CON_BTN_Luftwaffe, 530, 310, 110, 30, "Luftwaffe")
ButtonGadget(#CON_BTN_Heer, 530, 350, 110, 30, "Heer")
ButtonGadget(#CON_BTN_Land, 530, 390, 110, 30, "Land")
;ButtonGadget(#CON_BTN_Diplomatie, 650, 270, 110, 30, "Diplomatie")
ButtonGadget(#CON_BTN_Fertig, 650, 490, 110, 30, "Fertig")
ImageGadget(#CON_IMG_Eigenfarbe, 530, 190, 30, 30, UseImage(#IMG_Farbe), #PB_Image_Border)
TextGadget(#CON_TXT_Runde, 580, 200, 150, 20, "Runde: " + Str(player(Spieler_nr)\Runde))
ButtonGadget(#CON_BTN_Spionage, 650, 310, 110, 30, "Spionage")
ButtonGadget(#CON_BTN_Angriff, 530, 440, 110, 30, "Angriff auf...")
;}
; Spielregeln anzeigen
Paint_Info() ; hält das Spiel bei Runde 0 an
Spieler_nr = -1
Repeat ; Schleife bis alles für den Spielstart parat ist
;{- Spielart abfragen
t.l = -1
Repeat ; solange, bis eine Verbindung steht
If MessageRequester("Spielart wählen", " Wollen Sie ein neues Spiel starten (Ja)" + Chr(13) + Chr(10) + "Oder einem bereits bestehendem Spiel beitreten (Nein)", #PB_MessageRequester_YesNo) = 6
If CreateFile(0, Ownpath + "ServerParam.txt")
WriteStringN("1000, Spiel" + FormatDate("%yy%mm%dd%hh%ii%ss", Date()))
CloseFile(0)
EndIf
If RunProgram(Ownpath + "Entscheidungen Server.exe", "", "") ; Startet den Server
;{ meldet sich beim Server an
AddElement(LAN_Client())
LAN_Client()\IP_Name = "127.0.0.1" ; der eigene Rechner
Port = 1000
NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port)
If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
LAN_Client()\Aktiv_Server = NetzwerkID
Debug "netzwerkID gefunden: " + Str(NetzwerkID)
Msg.s = Space(20)
If ReceiveNetworkData(NetzwerkID, @Msg, 20)
Debug "received: " + Msg
LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
Msg = RTrim(Msg)
LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
c + 1
;If MessageRequester("Spielserver gefunden", "Es wurde folgendes Spiel gefunden" + Chr(13) + Chr(10) + Chr(13) + Chr(10) + LAN_Client()\Spiel_Name + " mit bisher " + Str(LAN_Client()\Spieler_bisher) + " Spielern" + Chr(13) + Chr(10) + Chr(13) + Chr(10) +"Wollen Sie an diesem Spiel mitspielen", #PB_MessageRequester_YesNo) = 6
t = Register_at_Server() ; am Server anmelden
; Else
; t = -1
; EndIf
EndIf
Else
MessageRequester("Fehler", "An der angegebenen Verbindung wurde kein Spielserver gefunden")
t = -1 ; Neuer Versuch
EndIf
;}
Else
MessageRequester("Fehler", "Kann kein neues Spiel starten" + Chr(13) + Chr(10) + "Versuchen sie, die Datei 'Entscheidungen Server' manuell zu starten")
EndIf
Else ; bei bestehndem Spiel anmelden
If MessageRequester("Verbindungswahl", " Wollen Sie die IP-Adresse des Servers selbst eingeben" + Chr(13) + Chr(10) + "Oder das LAN nach einem bereits bestehendem Spiel durchsuchen (Nein)", #PB_MessageRequester_YesNo) = 6
; die Daten selbst eingeben
t = Input_Server_Connections() ; 1, wenn eingegeben oder -1 wenn abbruch
If t = 1
;{ Ist an der angegebenen Verbindung ein Spielserver
NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port)
If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
LAN_Client()\Aktiv_Server = NetzwerkID
Debug "netzwerkID gefunden: " + Str(NetzwerkID)
Msg.s = Space(20)
If ReceiveNetworkData(NetzwerkID, @Msg, 20)
Debug "received: " + Msg
LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
Msg = RTrim(Msg)
LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
c + 1
If MessageRequester("Spielserver gefunden", "Es wurde folgendes Spiel gefunden" + Chr(13) + Chr(10) + Chr(13) + Chr(10) + LAN_Client()\Spiel_Name + " mit bisher " + Str(LAN_Client()\Spieler_bisher) + " Spielern" + Chr(13) + Chr(10) + Chr(13) + Chr(10) +"Wollen Sie an diesem Spiel mitspielen", #PB_MessageRequester_YesNo) = 6
t = Register_at_Server()
Else
t = -1
EndIf
EndIf
Else
MessageRequester("Fehler", "An der angegebenen Verbindung wurde kein Spielserver gefunden")
t = -1 ; Neuer Versuch
EndIf
;}
EndIf
Else
;{ LAN durchsuchen und am Server anmelden
; Welche Clients gibts im Lan
Debug "get lan list"
GetLANList()
;{ teste die Lan-Computer auf Spiel-Server
Port.l = 1000
c.l = 0
ResetList(LAN_Client())
While NextElement(LAN_Client())
Debug Str(ListIndex(LAN_Client())) + "- " + LAN_Client()\Name + " -> " + LAN_Client()\IP_Name
; auf welchen Clients läuft ein Server für das Spiel
NetzwerkID = OpenNetworkConnection(LAN_Client()\IP_Name, Port)
If NetzwerkID ; wenn die Verbindung aufgebaut werden konnte
LAN_Client()\Aktiv_Server = NetzwerkID
Debug "netzwerkID gefunden: " + Str(NetzwerkID)
Msg.s = Space(20)
If ReceiveNetworkData(NetzwerkID, @Msg, 20)
Debug "received: " + Msg
LAN_Client()\Spieler_bisher = Val(Left(Msg, 1))
Msg = RTrim(Msg)
LAN_Client()\Spiel_Name = Right(Msg, Len(Msg)-1)
Debug "Spiel gefunden: " + LAN_Client()\Spiel_Name
c + 1
EndIf
EndIf
Wend
Debug "alle server getestet"
ResetList(LAN_Client())
While NextElement(LAN_Client())
; zeigt die gefunden server, wenn die letzte Zahl <> 0, läuft dort ein Server
Debug Str(ListIndex(LAN_Client())) + "- " + LAN_Client()\Name + " -> " + LAN_Client()\IP_Name + " - Erg: " + Str(LAN_Client()\Aktiv_Server)
Wend
;}
;{ Auswählen, welches Spiel mitgespielt werden soll
Spieler_nr = -1 ; 1, wenn angemeldet
If c
t = Open_WND_Join_Game() ; wählt ein Spiel aus und schliesst die offenen Verbindungen zu anderen Spielservern
Debug "t: " + Str(t)
If t > -1 ; Spiel wurde ausgewählt
; die Verbindungsdaten übertragen
SelectElement(LAN_Client(), t)
Debug "listindex: " + Str(ListIndex(LAN_Client()))
NetzwerkID = LAN_Client()\Aktiv_Server
SpielName.s = LAN_Client()\Spiel_Name
; die Anmeldung am Spielserver machen
Debug "verbindungsdaten: ID: " + Str(NetzwerkID) + ". " + SpielName
t = Register_at_Server()
EndIf
Else
MessageRequester("Problem", "Keine Spiele zum Mitspielen vorhanden")
t = -1
EndIf
;}
;}
EndIf
EndIf
Until t <> -1
;}
;{- Warte auf Spielbeginn
Debug "warte auf Spielstart - spielrnr " + Str(Spieler_nr)
If OpenWindow(#WND_WAITSTART, 216, 168, 414, 132, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar , "Warten auf Spielstart", UseWindow(#WND_CON))
If CreateGadgetList(WindowID())
ProgressBarGadget(#WND_WAITSTART_PBAR, 20, 20, 360, 20, 0, 10, #PB_ProgressBar_Smooth)
TextGadget(#WND_WAITSTART_TXT_SpielerBisher, 20, 50, 180, 20, "Bisher angemeldete Spieler: " + Str(LAN_Client()\Spieler_bisher), #PB_Text_Border)
ButtonGadget(#WND_WAITSTART_BTN_Abbruch, 150, 100, 80, 20, "Abbrechen")
If Spieler_nr = 0 ; wenn Startspieler, der darf Spiel evtl. früher starten
ButtonGadget(#WND_WAITSTART_BTN_Start, 310, 100, 80, 20, "Spiel starten")
EndIf
; Progressbar setzen
Debug "Spieler bisher: " + Str(LAN_Client()\Spieler_bisher)
SetGadgetState(#WND_WAITSTART_PBAR, LAN_Client()\Spieler_bisher)
Repeat ; Start of the event loop
Event = WindowEvent() ; This line waits until an event is received from Windows
GadgetID = EventGadgetID() ; Is it a gadget event?
If NetworkClientEvent(NetzwerkID) = 2 ; Abfragen ob Spielstart erfolgt oder neuer Spieler dabei
Msg = " "
ReceiveNetworkData(NetzwerkID, @Msg, 2)
Msg = RTrim(Msg)
Debug "eingang für SPielstart: " + Msg + " / " + Str(Val(Msg))
If Msg <> "ST" ; wenn nicht Spielstart, dann neuer Mitspieler
Debug "msg nun: " + Msg
SetGadgetState(#WND_WAITSTART_PBAR, Val(Msg))
SetGadgetText(#WND_WAITSTART_TXT_SpielerBisher, "Bisher angemeldete Spieler: " + Msg)
EndIf
EndIf
If Event = #PB_EventGadget
If GadgetID = #WND_WAITSTART_BTN_Start
; Sende Startcode an Server
Msg = "ST"
SendNetworkData(NetzwerkID, @Msg, 2)
Msg = " " ; Nun auf die Startbestätigung warten
ElseIf GadgetID = #WND_WAITSTART_BTN_Abbruch
Event = #PB_Event_CloseWindow
EndIf
EndIf
Delay(10)
Until Event = #PB_Event_CloseWindow Or Msg = "ST" ; End of the event loop
Event = 0
CloseWindow(#WND_WAITSTART)
; Warte auf die Startdaten vom Server
Debug "warte auf Spieldaten - spielbeginn"
t = Receive_Game_Data()
EndIf
EndIf
Until t <> -1
;}
Debug "runde: " +Str(Runde)
Paint_Info()
Refresh_Data() ; vorab 1x aufbauen
Repeat ;{- Aktionsschleife
Event = WindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadgetID() ; Is it a gadget event?
EventType = EventType() ; The event type
; Get_Net_Data() ; testet, ob Daten vom Server gekommen sind
If Runde_fertig
Receive_Game_Data() ; wenn fertig, warte auf die nächste Runde
Paint_Info()
Refresh_Data()
EndIf
If Event = #PB_EventGadget
If GadgetID = #CON_BTN_Prod
If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
If player(Spieler_nr)\Produktion < player(Spieler_nr)\Land
player(Spieler_nr)\Aktionspunkte - 1
player(Spieler_nr)\Produktion + 1
Refresh_Data()
Else
MessageRequester("Problem", "Nicht genug Land, um weitere Produktion zu bauen")
EndIf
EndIf
ElseIf GadgetID = #CON_BTN_Luftwaffe
If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
player(Spieler_nr)\Aktionspunkte - 1
player(Spieler_nr)\Luftwaffe + 1
Refresh_Data()
EndIf
ElseIf GadgetID = #CON_BTN_Heer
If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
player(Spieler_nr)\Aktionspunkte - 1
player(Spieler_nr)\Heer + 1
Refresh_Data()
EndIf
ElseIf GadgetID = #CON_BTN_Diplomatie
ElseIf GadgetID = #CON_BTN_Spionage
; Zeige die Daten der Gegner an
If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
player(Spieler_nr)\Aktionspunkte - 1
Spionage = 1
Paint_Info()
Refresh_Data()
DisableGadget(#CON_BTN_Spionage, 1)
EndIf
ElseIf GadgetID = #CON_BTN_Angriff
temp.l = Choose_Victim()
If temp <> -1
player(Spieler_nr)\Victim = Choose_Victim()
EndIf
Refresh_Data()
ElseIf GadgetID = #CON_BTN_Land
If Runde_fertig = 0 And player(Spieler_nr)\Aktionspunkte
player(Spieler_nr)\Aktionspunkte - 1
player(Spieler_nr)\Land + 1
Paint_Info()
Refresh_Data()
DisableGadget(#CON_BTN_Spionage, 1)
EndIf
ElseIf GadgetID = #CON_BTN_Fertig
; Die Daten an den Server senden
If Runde_fertig = 0
Send_Game_Data()
Runde_fertig = 1
EndIf
EndIf
EndIf
;}
Delay(10)
Until Event = #PB_Event_CloseWindow ; End of the event loop
EndIf
EndIf
EndProcedure
;}
;- das eigentliche Spiel
Open_Game_Win()
End
Code: Alles auswählen
;{- Konstanten
#MAX_CLIENTS = 8
;}
;{- Die Spieldaten
Structure ply
Aktiv.l ; =1, wenn Spieler aktiv
Runde.l ; Rundennummer
Aktionspunkte.l ; die restlichen Aktionspunkte für diese Runde
Produktion.l ; Ergibt die Aktionspunkte
Luftwaffe.l ; Anzahl der Flieger
Heer.l ; Anzahl der Truppen
Land.l ; Landgrösse
Victim.l ; = -1, wenn niemand angegriffen werden soll, ansonsten die Spielernummer
Victim_davor.l ; speichert das Ziel der letzten Runde, wenn keines, dann -1
EndStructure
Dim player.ply(#MAX_CLIENTS)
Global Runde.l ; die neue Runde, die die Spieler gerade bearbeiten
Global StartSpiel.l ; = 1, wenn das Spiel gestartet werden soll
Dim Client.l(#MAX_CLIENTS) ; Die Verbindungsdaten für die Clients
Dim Daten.l(#MAX_CLIENTS) ; = 1, wenn die Daten dieser Runde vom Spieler eingegangen sind
;}
;{- Proceduren
; Core
Procedure ArraySize(*Array)
ProcedureReturn PeekL(*Array-8)
EndProcedure
Procedure Init_Game()
; erstellt ein neues Spiel
Runde = 1
Dim Daten.l(#MAX_CLIENTS) ; alle Eingangsflag auf 0 setzen
For x = 0 To #MAX_CLIENTS
If Client(x)
player(x)\Aktiv = 1 ; =1, wenn Spieler aktiv
Else
player(x)\Aktiv = 0
EndIf
player(x)\Runde = Runde ; Rundennummer
player(x)\Produktion = 2 ; Ergibt die Aktionspunkte
player(x)\Aktionspunkte = player(x)\Produktion
player(x)\Luftwaffe = 0 ; Anzahl der Flieger
player(x)\Heer = 0 ; Anzahl der Truppen
player(x)\Land = 10 ; Landgrösse
player(x)\Victim = -1
player(x)\Victim_davor = -1
Next
Debug "init game"
EndProcedure
Procedure Rundenauswertung()
; wertet die Runde aus und sendet die neuen Daten an alle Spieler
Runde + 1
PrintN("Werte Runde: " + Str(Runde) + " aus")
For x = 0 To #MAX_CLIENTS
; Nicht versorgte Armeeteile abbauen - d.h. Nach einem Kampf kann die Armee in der nächsten Runde noch einmal kämpfen
While player(x)\Produktion < player(x)\Luftwaffe + player(x)\Heer
If player(x)\Luftwaffe + player(x)\Heer - player(x)\Produktion > 2
player(x)\Luftwaffe - 1
player(x)\Heer - 1
Else
player(x)\Luftwaffe - 1
EndIf
Wend
; kämpfe auswerten
Beute.l = 0
If player(x)\Victim > -1 ; wenn Krieg geführt werden soll
v.l = player(x)\Victim ; Opfervar
;{ Luftwaffe
If player(x)\Luftwaffe > player(v)\Luftwaffe
diff = player(x)\Luftwaffe - player(v)\Luftwaffe
player(v)\Produktion = player(v)\Produktion - diff ; Zerstörung der Produktion
If player(v)\Produktion < 0
player(v)\Produktion = 0
EndIf
; Verluste
If dif < 2 ; mindestens 1
player(x)\Luftwaffe - 1
Else
player(x)\Luftwaffe = player(x)\Luftwaffe - diff>>1
EndIf
player(v)\Luftwaffe >> 1 ; halbieren
Else
; Verluste
diff = player(v)\Luftwaffe - player(x)\Luftwaffe ; verteidiger > angreifer
If diff < 2 ; mindestens 1
player(v)\Luftwaffe - 1
Else
player(v)\Luftwaffe = player(v)\Luftwaffe - diff>>1
EndIf
player(x)\Luftwaffe >> 1 ; halbieren
EndIf
;}
;{Heer
If player(x)\Heer > player(v)\Heer
Beute = player(x)\Heer - player(v)\Heer
diff = Beute
If Beute > player(v)\Land
Beute = player(v)\Land - 1
EndIf
player(v)\Land = player(v)\Land - Beute ; Zerstörung der Produktion
player(x)\Land = player(x)\Land + Beute
; Verluste
If diff < 2 ; mindestens 1
player(x)\Heer - 1
Else
player(x)\Heer = player(x)\Heer - diff>>1
EndIf
player(v)\Heer >> 1 ; halbieren
Else
; Verluste
diff = player(v)\Heer - player(x)\Heer ; verteidiger > angreifer
If diff < 2 ; mindestens 1
player(v)\Heer - 1
Else
player(v)\Heer = player(v)\Heer - diff>>1
EndIf
player(x)\Heer >> 1 ; halbieren
EndIf
;}
If player(v)\Land < player(v)\Produktion
player(v)\Produktion = player(v)\Land
EndIf
EndIf
; Neue Aktionspunkte setzen
player(x)\Aktionspunkte = player(x)\Produktion
If player(x)\Aktionspunkte = 0
player(x)\Aktionspunkte = 1
EndIf
player(x)\Victim_davor = player(x)\Victim
player(x)\Victim = -1
player(x)\Runde = Runde
Next
PrintN("Spiel geht nun in Runde " + Str(Runde))
EndProcedure
Procedure Start_Waiting_Game()
; startet das wartende Spiel
Init_Game() ; Spieldaten für Start setzen
For y = 0 To #MAX_CLIENTS
If player(y)\Aktiv
Msg.s = "ST"
SendNetworkData(Client(y), @Msg, 2)
Debug "sende Spielstart an Spielerplatz: " + Str(y) + " / " + Str(Client(y))
Debug "sende anzahl: " + Str(SizeOf(ply) * ArraySize(@player()))
SendNetworkData(Client(y), @player(), SizeOf(ply) * ArraySize(@player())); die Daten den Spielrn zusenden
Debug "sende Spieldaten an Spielerplatz: " + Str(y)
EndIf
Next
PrintN("Spiel gestartet")
EndProcedure
;}
;{- Den Server erstellen
OpenConsole()
If InitNetwork() = 0
PrintN("Das Netzwerksystem konnte nicht gestartet werden")
PrintN("Das Programm wird in 3 Sekunden beendet")
If FileSize("ServerParam.txt") > -1
DeleteFile("ServerParam.txt")
EndIf
Delay(3000)
End
EndIf
If ReadFile(0, "ServerParam.txt")
cl.s = ReadString()
Port.l = Val(RTrim(StringField(cl, 1, ", ")))
SpielName.s = RTrim(StringField(cl, 2, ", "))
CloseFile(0)
DeleteFile("ServerParam.txt")
Else
PrintN("An welchem Port soll der Server lauschen?")
Port.l = Val(Input())
PrintN("")
PrintN("Geben Sie den Spielnamen an (max. 19 Zeichen)?")
SpielName.s =Input()
EndIf
If Len(SpielName) > 19 ; länge des Spielnamens überprüfen
SpielName = Left(SpielName, 19)
EndIf
If Port < 1000 ; die portnummer überprüfen
Port = 1000
EndIf
If Port > 7000
Port = 7000
EndIf
PrintN("")
PrintN("Starte Spiel " + SpielName + " an Port " + Str(Port))
PrintN("")
If CreateNetworkServer(Port) = 0
PrintN("Server konnte nicht erstellt werden")
Delay(3000)
End
Else
PrintN("Server wurde erstellt")
EndIf
;}
;{- Die Aktionsschleife
Repeat
Select NetworkServerEvent()
Case 1 ;{ a new client has been connected to the server
t = NetworkClientID()
c.l = 0
For x = 0 To #MAX_CLIENTS
If Client(x) <> 0
c + 1
EndIf
Next
Msg.s = Str(c) + SpielName
Msg = Msg + Space(20 - Len(Msg))
SendNetworkData(t, @Msg, 20) ; sendet die bisherige Spieleranzahl und den SPielnamen
PrintN("Serveranfrage - ID: " + Str(t))
;}
Case 2 ;{ Raw Data has been received (To be Read with ReceiveNetworkData())
t = NetworkClientID() ; sender speichern
; testen, ob Sender in Liste eingetragen
cnt.l = -1 ; nächster freier Platz
x.l = -1 ; index des Spielers, von dem die Daten kommen
For y = 0 To #MAX_CLIENTS
If Client(y) = t
x = y
EndIf
If Client(y) = 0 And cnt = -1
cnt = y
EndIf
Next
Debug "x: " + Str(x)
If x > -1 ; wenn schon in der Clientliste
If StartSpiel = 0
; erhalte Spielstart-daten
Msg = " "
ReceiveNetworkData(t, @Msg, 2) ; Daten empfangen
If Msg = "ST"
Debug "Code für Spielstart erhalten"
StartSpiel = 1 ; starte Spiel
Start_Waiting_Game()
EndIf
Else
Debug "Erhalte Daten von spieler (platz) " + Str(x) + " - verb: " + Str(t)
Daten(x) = 1 ; die Daten dieses Spielers als erhalten markieren
ReceiveNetworkData(t, @player(x), SizeOf(ply)) ; ins array schreiben
;{ Checke, ob das der letzte Spieler war
fertig.l = 1
For y = 0 To #MAX_CLIENTS
If player(y)\Aktiv
If Daten(y) = 0
fertig = 0 ; noch nicht fertig
EndIf
EndIf
Next
Debug "fertig: " + Str(fertig)
;}
If fertig ;{ Runde auswerten und Daten zurückschreiben
Rundenauswertung()
For y = 0 To #MAX_CLIENTS ; Daten verschicken und Array zurücksetzen
If Client(y)
Debug "§schicke spieler daten für runde " + Str(Runde) + " Spieler: " + Str(y)
SendNetworkData(Client(y), @player(), SizeOf(ply) * ArraySize(@player()))
Daten(y) = 0
EndIf
Next
;}
EndIf
EndIf
Else
Debug "neuer client sendet daten"
; Will sich der Client anmelden?
Msg.s = " " ; erwarte einen Anmeldestring
ReceiveNetworkData(t, @Msg, 1)
Debug "gesendet: " + Msg
If Msg = "1" ; Anmeldeversuch
If cnt > -1 ; wenn noch Platz in der Clientliste war
Client(cnt) = t ; in die Liste aufnehmen
PrintN("Neuer Client auf platz " + Str(cnt) + " - NR. " + Str(Client(cnt)))
Msg.s = "1-" + Str(cnt)
SendNetworkData(t, @Msg, 3) ; sende dem Client - Bestätigung Warteliste
;{ Schicke allen Spielern die Neue Spielerzahl
Msg.s = Str(cnt+1)
For y = 0 To #MAX_CLIENTS
If Client(y)
SendNetworkData(Client(y), @Msg, 1)
EndIf
Next
;}
Debug "bestätigung: Warten verschickt: " + Msg
If cnt = #MAX_CLIENTS
; Maximale Anzahl erreicht
Debug "alle Spieler da - Spiel sollte hier starten"
Start_Waiting_Game()
EndIf
Else
PrintN("Neuer Client versuchte sich einzuloggen - kein Platz auf Liste")
Msg.s = "9-"
SendNetworkData(t, @Msg, 2) ; sende dem Client - Absage wegen Voll
Debug "absage geschickt: " + Msg
EndIf
EndIf
EndIf
;}
Case 3 ; a file has been received (To be Read with ReceiveNetworkFile())
Case 4 ;{ a client has quit the server (deconnection)
t = NetworkClientID() ; sender speichern
; testen, ob Sender in Liste eingetragen
c.l = 0 ;flag für Abmeldung von Spieler
rest.l = 0
For x = 0 To #MAX_CLIENTS
If Client(x) = t
Client(x) = 0 ; aus der Liste austragen
PrintN("Client hat sich ausgeloggt - Nr: " + Str(x))
c + 1
EndIf
If Client(x) <> 0 ; aktiver Spieler
rest + 1
EndIf
Next
If c ; Schicke allen Spielern die Neue Spielerzahl
Msg.s = Str(rest)
For y = 0 To #MAX_CLIENTS
If Client(y)
SendNetworkData(Client(y), @Msg, 1)
EndIf
Next
EndIf
If rest = 0 And StartSpiel ; keine Spieler mehr
StartSpiel = 0
PrintN("Spiel beendet - keine Spieler mehr")
EndIf
If c = 0
PrintN("Ein Anfrager hat sich ausgeloggt - ID: " + Str(t))
EndIf
;}
EndSelect
Delay(1)
ForEver
;}
Wenns jemand mal ausprobiert, wäre ich über ne Rückmeldung dankbar.
P.S. Ich habe versucht, keine API zu verwenden (das mit dem Exepath ist nur zum debuggen gewesen, kann man rausschmeissen).
Es sollte also auch unter Linux laufen.
Wenn das mal jemand testen könnte und mir was dazu sagen könnte, wäre ich froh.