DBRecord struct UserName db 64 dup (?) PassWord db 64 dup (?) Email db 64 dup (?) DBRecord ends LoadObjects DiskStream ;This structure describes the packet header of this protocol. ;There might be a payload following each header, but maybe not. LobbyPacket struct dProtocolID dd ? dServiceCode dd ? ;what kind of request dPacketSize dd ? ;sizeof packet header + packet payload LobbyPacket ends REQ_AUTH equ 0 ;Someone wishes to authenticate REQ_LIST_SERVERS equ 1 ;requesting a list of GameServers REQ_LIST_PLAYERS equ 2 ;query a GameServer for its list of Players REQ_HOST_SERVER equ 3 ;requesting to be advertised as a host server LobbyServerProtocolID equ 25775 Object LobbyServerProtocol,LobbyServerProtocolID,NetworkProtocol RedefineMethod Done RedefineMethod Init, Pointer, Pointer;pOwner, pAppEventSink RedefineMethod FindDelimiter, Pointer, Pointer;pClient, pXOVL RedefineMethod ProcessReceivedData,Pointer ;pClient RedefineMethod OnConnectCompleted, Pointer, dword ;pClient, dError RedefineMethod OnAcceptCompleted, Pointer, dword ;pClient, dError VirtualMethod Authenticate, LPSTR,LPSTR,LPSTR Embed Database, DiskStream ObjectEnd if IMPLEMENT ; 覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧 Method LobbyServerProtocol.Init,uses esi, pOwner, pAppEventSink SetObject esi ACall esi.Init, pOwner, pAppEventSink ;First thing we'll do is add a ClientGroup to track GameServers mov edx,pOwner OCall [edx].NetEngine.RootClientGroup::ClientGroup.AddSubGroup,$OfsCStr("GameServers"),$OfsCStr("Servers which are hosting games") ;Now we'll fire up our database OCall [esi].Database::DiskStream.Init,esi,$OfsCStr("Database.data") MethodEnd Method LobbyServerProtocol.Done,uses esi SetObject esi OCall [esi].Database::DiskStream.Done ACall Done MethodEnd ;Scan the Database for user/pass ;Possible return values are: ;0 = username was just registered ;1 = username exists but password is wrong ;2 = username exists and password is correct Method LobbyServerProtocol.Authenticate,uses esi,pUserName,pPassword,pEmail LOCAL sighs LOCAL dbr:DBRecord LOCAL result SetObject esi DbgWarning "Authenticating" mov sighs,$OCall ([esi].Database::DiskStream.GetSize) mov result,0 .if sighs!=0 xor ebx,ebx invoke SetFilePointer,[esi].Database.hFile,0,0,FILE_BEGIN .while ebx < sighs OCall [esi].Database::DiskStream.BinRead,addr dbr,sizeof dbr invoke lstrcmpi,pUserName,addr dbr.UserName .if eax==0 inc result invoke lstrcmp,pPassword,addr dbr.PassWord .if eax==0 inc result .endif .break .endif add ebx,sizeof DBRecord .endw .endif .if result==0 ;The username does not exist - register it now ;(we're already at the end of the database file, ;so there's no need to set the filepointer) invoke RtlZeroMemory,addr dbr,sizeof dbr invoke lstrcpy,addr dbr.UserName,pUserName invoke lstrcpy,addr dbr.PassWord,pPassword invoke lstrcpy,addr dbr.Email,pEmail OCall [esi].Database::DiskStream.BinWrite,addr dbr,sizeof dbr .endif mov eax, result MethodEnd ;ERROR_BADPROTOCOL - The buffer content is not following our Protocol - the Client will get Booted for this offence ;ERROR_USERQUIT - The user sent a nice QUIT message using our Protocol - the Client will get Booted for this ;Positive INT32 - This many Bytes are part of the Complete Packet ;NULL - We need more data Method LobbyServerProtocol.FindDelimiter,uses esi edi,pClient,pXOVL LOCAL packetsize mov edi,pXOVL ;Do we have at least 4 bytes? .if [edi].XOVL.bytesused<4 return NULL .endif ;Do the first 4 bytes match our protocol identifier? mov eax,[edi].XOVL.pbuforig .if dword ptr[eax]!="YBOL" return ERROR_BADPROTOCOL .endif ;Do we have at least a full packet header? .if [edi].XOVL.bytesused