Well i was actually in the process of rewriting this to simplify it using array indexing so atm might be a bit confusing the way i handle connects and disconnects. was basically a rough draft of the sever side code.
// Created: 20-07-19
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Runes OF Averend" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
`setsuncolor(128,128,100)
setsunactive(0)
SetGenerateMipmaps(1)
setAmbientColor(90,90,90)
SetVSync(1)
SetAntialiasMode(4)
createpointlight (10,0,1,-2,8,255,0,0)
`SetSunDirection(4,-240,40)
#include "import.agc"
Loadimporter()
loadmodel("AGKCompatible.x")
`loadmodel("test.x")
createpointlight (1,0,15,0,35,255,255,200)
do
mouse_controls()
Sync()
loop
type player_net_info
IP as string
Socketnum as integer
PlayerNum as integer
Heartbeat as integer
Bytes as integer
playerstring as string[5]
Name as string
Email as string
PendLogin as integer
Current_Player_Character as integer
loadcharanddelete as integer
Loaded_Char_num as integer[1] // the char loaded in game
loaded_char_part_list as integer[100] //list of parts for loaded character
endtype
function include()
global getsocket as integer
global isoktologin as integer
global highest_player_socket_to_check
highest_player_socket_to_check=11
global Player as player_net_info[8000]
#constant maxplayersallowed 8000
Global ServerIP as string
Global ServerPort as integer
Global socketstartrange as integer:socketstartrange=100000
Global socketendrange as integer:socketendrange=200000
Global listener:listener=3
Global currentplayercount=11
Global Error
global errormessage$
global ServerTimeout as integer
global deletedheartbeats
endfunction
FUNCTION StartServer(listener as integer ,ServerIP as string,ServerPort as integer) //returns 1 or 0
include()
fail=0
//starts a server and returns status 1 or 0
retry:
status=CreateSocketListener(listener ,ServerIP,ServerPort)
if status =0
gosub retry:
inc fail,1
endif
if fail = 6
Error=1
errormessage$="Failed to connect to "+ServerIP+ "on Port"+ str(ServerPort)
endif
endfunction status
function Error()
if error=1
print(errormessage$)
endif
endfunction
`Get new connections to server
function listen_and_asighn(listener) //only runs if new connection is esablished
function Get_new_connections()
tcpsocket=GetSocketListenerConnection(1)
udpsocket=GetSocketListenerConnection(2)
if tcpsocket > 1 and UDPsocket >1
tempip1$=getsocketremoteip(tcpsocket)
tempip2$=getsocketremoteip(udpsocket)
//if ban list ok then proceed
if tempip1$=tempip2$ and len(tempip1$)>4
asighn_new_sockets(tcpsocket,udpsocket,tempip1$,tempip2$)
endif
endif
endfunction
tempsocket=GetSocketListenerConnection(listener)
if tempsocket>0
getsocket=tempsocket
tempsocket=0
endif
checkvailidlogin()
if isoktologin=1
inc currentplayercount,1 // add 1 more player num to the game
inc highest_player_socket_to_check,1
if currentplayercount >= maxplayersallowed
deletesocket(getsocket) //getsocket return current socket since it hasnt been loop cleared yet
dec currentplayercount ,1 // remove player just added after deleting socket
getsocket=0
gosub exit_player_assighnment:
endif
if serverisjoining=1
for i = 1 to 10
`check for empty slots and assighn new socket to empty slot
if player[i].socketnum=0
player[i].Name="Server "+ ServerName$
player[i].socketnum=getsocket
player[i].Playernum=i
player[i].IP=Serverip$
player[i].Heartbeat=getseconds()
goto skip2: //must have loop runs 1 extra time if not added
endif
next
skip2:
isoktologin=0
serverisjoining=0
getsocket=0
temp_string_for_unknown_user$=""
temp_string_for_unknown_user2$=""
endif
if serverisjoining=0 and isoktologin=1
for i = 11 to currentplayercount
`check for empty slots and assighn new socket to empty slot
if player[i].socketnum=0
player[i].Name=adduserthendeleteme$:adduserthendeleteme$=""
player[i].socketnum=getsocket
player[i].Playernum=i
player[i].IP=adduseripthendeleteme$:adduseripthendeleteme$=""
player[i].Heartbeat=getseconds()
player[i].PendLogin=1
goto skip3: //must have loop runs 1 extra time if not added
endif
next
skip3:
isoktologin=0
serverisjoining=0
getsocket=0
`temp_string_for_unknown_user2$=""
endif
endif
exit_player_assighnment:
endfunction
function del_dead_heartbeats(LoginServerTimeout)
count=0
for i = 1 to highest_player_socket_to_check
if timer()-player[i].Heartbeat > LoginServerTimeout
if GetSocketExists(player[i].socketnum)=1
deletesocket (player[i].socketnum)
player[i].name=""
player[i].playernum=0
player[i].socketnum=0
player[i].heartbeat=0
player[i].IP=""
player[i].Bytes=0
player[i].playerstring[1]=""
player[i].pendlogin=0
player[i].email=""
inc deletedheartbeats,1
if getsocketexists(player[highest_player_socket_to_check].socketnum)=0
dec highest_player_socket_to_check,1
endif
inc count ,1
endif
endif
next
dec currentplayercount,count
endfunction
function manually_delete_player(playernumber)
deletesocket (player[playernumber].socketnum)
player[playernumber].name=""
player[playernumber].playernum=0
player[playernumber].socketnum=0
player[playernumber].heartbeat=0
player[playernumber].IP=""
dec highest_player_socket_to_check,1
dec currentplayercount,1
endfunction
function runserver(ServerTimeout)
listen_and_asighn(listener)
getplayerstring()
SetPlayerHeartbeat()
getplayerstring()
SendServerHeartbeat(2)
getplayerstring()
del_dead_heartbeats(ServerTimeout)
getplayerstring()
Error() // lets us know if server port is blocked
getplayerstring()
connectplayerfromlogin()
getplayerstring()
endfunction
function GetPlayerString()
for i = 1 to highest_player_socket_to_check //1 to 11
if getsocketexists(Player[i].socketnum)=1
if GetSocketBytesAvailable(Player[i].socketnum)>=1
player[i].Heartbeat=GetSeconds()
getstring$=Getsocketstring(player[i].socketnum)
if left(getstring$,6)="TmpLog"
player[i].playerstring[2]=getstring$
getstring$=""
endif
if not (getstring$)="Thump"
player[i].PlayerString[1]=getstring$
getstring$=""
endif
if left(getstring$,5)="Char:" //load client selected character
character=val(right(getstring$,1))
Player[i].loadcharanddelete=character //srcfile=load_char_for_play.agc
Read_Player_File_load_character_internal(i,Player[i].loadcharanddelete)
getstring$=""
character=0
endif
getstring$=""
endif
endif
next
endfunction
function GetPlayerInt(PlayerNum)
if getsocketexists(player[PlayerNum].socketnum)=1
if GetSocketBytesAvailable(player[PlayerNum].socketnum)>1
PlayerInt=Getsocketinteger(player[PlayerNum].socketnum)
endif
endif
endfunction PlayerInt
function GetPlayerFloat(PlayerNum)
if getsocketexists(player[PlayerNum].socketnum)=1
if GetSocketBytesAvailable(Player[PlayerNum].SocketNum)>1
PlayerFloat=GetsocketFloat(Player[PlayerNum].SocketNum)
endif
endif
endfunction PlayerFloat
function SendPlayerString(PlayerNum,String$)
if player[PlayerNum].PlayerNum>0
SendSocketString(Player[PlayerNum].SocketNum,String$)
endif
endfunction
function SendPlayerInt(PlayerNum,Int)
if player[PlayerNum].Playernum > 0
SendSocketInteger(Player[PlayerNum].SocketNum,Int)
endif
endfunction
function SendPlayerFloat(PlayerNum,Decimal)
if player[PlayerNum].Playernum > 0
SendSocketfloat(Player[PlayerNum].SocketNum,Decimal)
endif
endfunction
function KickPlayer(PlayerNum,Reason$)
if player[PlayerNum].Playernum > 0
SendPlayerString(PlayerNum,Reason$)
DeleteSocket(Player[PlayerNum].SocketNum)
endif
endfunction
function PlayerExists(PlayerNum)
if Player[PlayerNum].PlayerNum >0
ret=1
else
ret=0
endif
endfunction ret
function SetPlayerHeartbeat()
for i = 1 to highest_player_socket_to_check
if Player[i].PlayerNum >0
if getsocketexists(Player[i].socketnum)=1
if GetSocketBytesAvailable(Player[i].SocketNum)>=1
player[i].Heartbeat=timer()
endif
endif
endif
next
endfunction
function GetPlayerHeartbeat(PlayerNum)
Heartbeat=Player[PlayerNum].Heartbeat
endfunction Heartbeat
function SendServerHeartbeat(Frequency)
global runonce///////
global start //////////
if runonce=0
start=getseconds()
runonce=1
endif
if getseconds()-start > Frequency
runonce=0
for i = 1 to highest_player_socket_to_check
if player[i].playernum>0
SendPlayerString(i,"Thump")
FlushSocket(Player[i].SocketNum)
endif
next
endif
endfunction
function GetPlayerIP(PlayerNum)
TempIP$=Player[PlayerNum].IP
endfunction TempIP$
function GetPlayerSocket(PlayerNum)
Tempsocket=Player[PlayerNum].Socketnum
endfunction Tempsocket
function GetPlayerCount()
count=currentplayercount
endfunction count
global serverName$
global ServerIP$
global serverisjoining=0
global temp_string_for_unknown_user$
global temp_string_for_unknown_user2$
global tempname as string [200]
global tempip as string[200]
global templogintimer as float[200]
global getloginip$
global adduserthendeleteme$
global adduseripthendeleteme$
function checkvailidlogin()
//getfromserver log server in
if getsocketexists(getsocket)=1 //if new connection established grab ip
getloginIP$=getsocketremoteip(getsocket) // grab ip
if getsocketbytesavailable(getsocket)>=1
temp_string_for_unknown_user$=getsocketstring(getsocket) //get data string from new socket
endif
endif
if left(temp_string_for_unknown_user$,6)="LogReq"
temp_string_for_unknown_user2$=temp_string_for_unknown_user$
temp_string_for_unknown_user$=""
endif
if left(temp_string_for_unknown_user$,11)="*#&%()@^$#:" //if data matches server password tell it its a server :num" on the end telling it server nam
tempservernum$=right(temp_string_for_unknown_user$,1)
ServerName$=tempservernum$
ServerIP$=getloginIP$ // assighn server ip then log it in
``temp_string_for_unknown_user$="" //dont reset
// dont reset this because the string has been read & cant be read again, need to use it to check for player if its not server
isoktologin=1
serverisjoining=1
getloginip$=""
temp_string_for_unknown_user$=""
temp_string_for_unknown_user2$=""// needs to be here if this has ran to this point then its a server logging in and this string has been assighned a value it cannot use
endif
// below code block. get server string to see if a new user info was sent to game server from login
getplayerstring()
if len(player[1].playerstring[2])>=1
TempPlayerString$=player[1].playerstring[2] // this is a log req comming from login server! [1]=loginserver
player[1].playerstring[2]=""
//reset so doesnt loop reapeat
//if temp login exists in serverstring start adding player into system
if left(TempPlayerstring$,6)="TmpLog"
//checkbanlist()
//ADD LATER if globalbanstatus=0 then login below
TempNameString$=truncatestring(TempPlayerString$,":")
TempPlayerName$=(right(TempNameString$,len(TempNameString$)-6))
TempPlayerIP$=right(TempPlayerString$,len(TempPlayerString$)-(len(TempPlayerName$)+7))
//assighn new player temparaily to server
//add temp users
for i = 1 to 100
if len(Tempname[i]) <1
TempName[i]=TempPlayerName$
TempIP[i]=TempPlayerIP$
TempLoginTimer[i]=timer()
goto exit4:
endif
next
exit4:
endif
endif
// delete temp login after 2 seconds
for i= 1 to 100
if timer()-templogintimer[i] >4
templogintimer[i]=0
tempip[i]=""
tempname[i]=""
TempPlayerIP$=""
TempPlayerName$=""
// add deletion of user scan ips prolly
endif
next
//check and perm add users
//check for useres connecting then check for existing temp id
global tempplayername2$
global tempplayerip2$
// getfromclient name and ip
if left(temp_string_for_unknown_user2$,6)="LogReq"
`end//works up to here
TempPlayerName2$=(right(temp_string_for_unknown_user2$,len(temp_string_for_unknown_user2$)-6))
TempPlayerIP2$=GetLoginIP$
`Temp_string_for_unknown_user2$=""
//check name and ip
ENDIF
if serverisjoining=0 and len(temp_string_for_unknown_user2$)>1
for i = 1 to 100
if TempIP[i]=TempPlayerIP2$ and len(TempIP[i])>4 and TempName[i]=TempPlayerName2$
isoktologin=1
adduserthendeleteme$=TempName[i]
adduseripthendeleteme$=TempIP[i]
TempIP[i]=""
TempName[i]=""
TempPlayerName2$=""
TempPlayerIP2$=""
temp_string_for_unknown_user2$=""
temp_string_for_unknown_user$=""
goto exit5:
endif
next
exit5:
`temp_string_for_unknown_user$=""//fail safe incase a condition is not met
temp_string_for_unknown_user$=""
temp_string_for_unknown_user2$=""
endif
endfunction
function connectplayerfromlogin() //getip and name from other server
`path$="raw:"+getreadpath()+"media/players/" //set the dir to check
`GetPlayerString()
`for i = 11 to highest_player_socket_to_check //if "makeplayer" from client string make a newe player file
`playerstring$=player[i].playerstring[1] // set a temp var to make code more readable then constantly referrencing an array easier on memory also
`if left(playerstring$,10) = "makeplayer"
`Player[i].Name=(right(playerstring$,len(playerstring$)-10))
`makefolder(path$+Player[i].Name)
`opentowrite(1,path$+Player[i].Name+"/"+Player[i].Name+".txt",0)
`writeline(1,"rawdoc")
`closefile(1)
`endif
`next
global path$
path$="raw:"+getreadpath()+"media/players/" //set the dir to check
for i = 11 to highest_player_socket_to_check // if loqreq from client load user files and send user files.
if len(Player[i].IP) >4 and player[i].PendLogin=1
countnumberofobjects=0
setfolder("Players")
setfolder(Player[i].Name)
filecount=getfilecount()
endfiles=filecount-1 // run below loop as many times as there ar files in the dir.
sendplayerstring(i,"LoadCharNums"+str(endfiles))
flushsocket(player[i].Socketnum)
for startfiles= 1 to endfiles
if getfileexists(path$+player[i].Name+"/"+str(startfiles)+Player[i].Name+".txt")=1
opentoread(5,path$+Player[i].Name+"/"+str(startfiles)+Player[i].Name+".txt")
//send file count to client so it knows how many files to look for
while FileEof(5)=0
chardata$=readline(5)
if right(chardata$,3)="mdl"
inc countnumberofobjects ,1
endif
sendplayerstring(i,chardata$)
flushsocket(player[i].socketnum) //does player 2 have a socket?
endwhile
if fileisopen(5)=1
closefile(5)
endif
endif
sendplayerstring(i,str(countnumberofobjects)+"Finish")
flushsocket(player[i].socketnum)
ountnumberofobjects=0
next
player[i].PendLogin=0
setfolder("..")
setfolder("..")
endif
next
endfunction