hedgewars/uFLNet.pas
branchqmlfrontend
changeset 10933 f1da4126a61c
parent 10931 384765cd0caf
child 10935 3a65fcd7c335
equal deleted inserted replaced
10931:384765cd0caf 10933:f1da4126a61c
    13 
    13 
    14 function getNextChar: char; forward;
    14 function getNextChar: char; forward;
    15 function getCurrChar: char; forward;
    15 function getCurrChar: char; forward;
    16 procedure sendNet(s: shortstring); forward;
    16 procedure sendNet(s: shortstring); forward;
    17 
    17 
    18 type TCmdType = (cmd_ASKPASSWORD, cmd_BANLIST, cmd_BYE, cmd_CHAT, cmd_CLIENT_FLAGS, cmd_CONNECTED, cmd_EM, cmd_HH_NUM, cmd_INFO, cmd_JOINED, cmd_JOINING, cmd_KICKED, cmd_LEFT, cmd_LOBBY_JOINED, cmd_LOBBY_LEFT, cmd_NICK, cmd_NOTICE, cmd_PING, cmd_PROTO, cmd_ROOMS, cmd_ROUND_FINISHED, cmd_RUN_GAME, cmd_SERVER_AUTH, cmd_SERVER_MESSAGE, cmd_SERVER_VARS, cmd_TEAM_ACCEPTED, cmd_TEAM_COLOR, cmd_WARNING, cmd___UNKNOWN__);
    18 type TCmdType = (cmd___UNKNOWN__, cmd_WARNING, cmd_TEAM_COLOR, cmd_TEAM_ACCEPTED, cmd_SERVER_VARS, cmd_SERVER_MESSAGE, cmd_SERVER_AUTH, cmd_RUN_GAME, cmd_ROUND_FINISHED, cmd_ROOMS, cmd_PROTO, cmd_PING, cmd_NOTICE, cmd_NICK, cmd_LOBBY_LEFT, cmd_LOBBY_JOINED, cmd_LEFT, cmd_KICKED, cmd_JOINING, cmd_JOINED, cmd_INFO, cmd_HH_NUM, cmd_EM, cmd_CONNECTED, cmd_CLIENT_FLAGS, cmd_CHAT, cmd_BYE, cmd_BANLIST, cmd_ASKPASSWORD);
    19 
    19 
    20 type
    20 type
    21     TNetState = (netDisconnected, netConnecting, netLoggedIn);
    21     TNetState = (netDisconnected, netConnecting, netLoggedIn);
    22     TParserState = record
    22     TParserState = record
    23                        cmd: TCmdType;
    23                        cmd: TCmdType;
    35 
    35 
    36 const commands: array[0..206] of integer = (12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -38, 11, 7, 0, 0, 0, 0, 0, -37, 0, 0, -36, 26, 4, 0, 0, -35, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 0, -33, 3, 0, -32, 7, 0, 0, 0, 0, 0, -31, 5, 0, 0, 0, -30, 11, 0, 0, 0, 3, 0, -29, 0, 0, 0, -28, 7, 0, 0, 0, 0, 0, -27, 22, 4, 0, 0, -26, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, -25, 0, 0, 0, 0, -24, 11, 4, 0, 0, -23, 0, 0, 0, 0, 0, -22, 10, 4, 0, 0, -21, 0, 0, 0, 0, -20, 27, 18, 4, 0, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, 0, -17, 25, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, -16, 8, 0, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, -14, 20, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, -12, 8, 0, 0, 0, 0, 0, 0, -11, 0, -10);
    36 const commands: array[0..206] of integer = (12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -38, 11, 7, 0, 0, 0, 0, 0, -37, 0, 0, -36, 26, 4, 0, 0, -35, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 0, -33, 3, 0, -32, 7, 0, 0, 0, 0, 0, -31, 5, 0, 0, 0, -30, 11, 0, 0, 0, 3, 0, -29, 0, 0, 0, -28, 7, 0, 0, 0, 0, 0, -27, 22, 4, 0, 0, -26, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, -25, 0, 0, 0, 0, -24, 11, 4, 0, 0, -23, 0, 0, 0, 0, 0, -22, 10, 4, 0, 0, -21, 0, 0, 0, 0, -20, 27, 18, 4, 0, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, 0, -17, 25, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, -16, 8, 0, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, -14, 20, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, -12, 8, 0, 0, 0, 0, 0, 0, -11, 0, -10);
    37 
    37 
    38 procedure handler_ASKPASSWORD;
    38 procedure handler_ASKPASSWORD;
    39 begin
    39 begin
    40     state.cmd:= cmd_ASKPASSWORD;
       
    41 end;
    40 end;
    42 
    41 
    43 procedure handler_BANLIST;
    42 procedure handler_BANLIST;
    44 begin
    43 begin
    45     state.cmd:= cmd_BANLIST;
       
    46 end;
    44 end;
    47 
    45 
    48 procedure handler_BYE;
    46 procedure handler_BYE;
    49 begin
    47 begin
    50     state.cmd:= cmd_BYE;
       
    51 end;
    48 end;
    52 
    49 
    53 procedure handler_CHAT;
    50 procedure handler_CHAT;
    54 begin
    51 begin
    55     state.cmd:= cmd_CHAT;
       
    56 end;
    52 end;
    57 
    53 
    58 procedure handler_CLIENT_FLAGS;
    54 procedure handler_CLIENT_FLAGS;
    59 begin
    55 begin
    60     state.cmd:= cmd_CLIENT_FLAGS;
       
    61 end;
    56 end;
    62 
    57 
    63 procedure handler_CONNECTED;
    58 procedure handler_CONNECTED;
    64 begin
    59 begin
    65     state.cmd:= cmd_CONNECTED;
       
    66 end;
    60 end;
    67 
    61 
    68 procedure handler_EM;
    62 procedure handler_EM;
    69 begin
    63 begin
    70     state.cmd:= cmd_EM;
       
    71 end;
    64 end;
    72 
    65 
    73 procedure handler_HH_NUM;
    66 procedure handler_HH_NUM;
    74 begin
    67 begin
    75     state.cmd:= cmd_HH_NUM;
       
    76 end;
    68 end;
    77 
    69 
    78 procedure handler_INFO;
    70 procedure handler_INFO;
    79 begin
    71 begin
    80     state.cmd:= cmd_INFO;
       
    81 end;
    72 end;
    82 
    73 
    83 procedure handler_JOINED;
    74 procedure handler_JOINED;
    84 begin
    75 begin
    85     state.cmd:= cmd_JOINED;
       
    86 end;
    76 end;
    87 
    77 
    88 procedure handler_JOINING;
    78 procedure handler_JOINING;
    89 begin
    79 begin
    90     state.cmd:= cmd_JOINING;
       
    91 end;
    80 end;
    92 
    81 
    93 procedure handler_KICKED;
    82 procedure handler_KICKED;
    94 begin
    83 begin
    95     state.cmd:= cmd_KICKED;
       
    96 end;
    84 end;
    97 
    85 
    98 procedure handler_LEFT;
    86 procedure handler_LEFT;
    99 begin
    87 begin
   100     state.cmd:= cmd_LEFT;
       
   101 end;
    88 end;
   102 
    89 
   103 procedure handler_LOBBY_JOINED;
    90 procedure handler_LOBBY_JOINED;
   104 begin
    91 begin
   105     state.cmd:= cmd_LOBBY_JOINED;
       
   106 end;
    92 end;
   107 
    93 
   108 procedure handler_LOBBY_LEFT;
    94 procedure handler_LOBBY_LEFT;
   109 begin
    95 begin
   110     state.cmd:= cmd_LOBBY_LEFT;
       
   111 end;
    96 end;
   112 
    97 
   113 procedure handler_NICK;
    98 procedure handler_NICK;
   114 begin
    99 begin
   115     state.cmd:= cmd_NICK;
       
   116 end;
   100 end;
   117 
   101 
   118 procedure handler_NOTICE;
   102 procedure handler_NOTICE;
   119 begin
   103 begin
   120     state.cmd:= cmd_NOTICE;
       
   121 end;
   104 end;
   122 
   105 
   123 procedure handler_PING;
   106 procedure handler_PING;
   124 begin
   107 begin
   125     state.cmd:= cmd_PING;
   108     sendNet('PONG')
   126 
       
   127     sendNet('PONG');
       
   128 end;
   109 end;
   129 
   110 
   130 procedure handler_PROTO;
   111 procedure handler_PROTO;
   131 begin
   112 begin
   132     state.cmd:= cmd_PROTO;
       
   133 end;
   113 end;
   134 
   114 
   135 procedure handler_ROOMS;
   115 procedure handler_ROOMS;
   136 begin
   116 begin
   137     state.cmd:= cmd_ROOMS;
       
   138 end;
   117 end;
   139 
   118 
   140 procedure handler_ROUND_FINISHED;
   119 procedure handler_ROUND_FINISHED;
   141 begin
   120 begin
   142     state.cmd:= cmd_ROUND_FINISHED;
       
   143 end;
   121 end;
   144 
   122 
   145 procedure handler_RUN_GAME;
   123 procedure handler_RUN_GAME;
   146 begin
   124 begin
   147     state.cmd:= cmd_RUN_GAME;
       
   148 end;
   125 end;
   149 
   126 
   150 procedure handler_SERVER_AUTH;
   127 procedure handler_SERVER_AUTH;
   151 begin
   128 begin
   152     state.cmd:= cmd_SERVER_AUTH;
       
   153 end;
   129 end;
   154 
   130 
   155 procedure handler_SERVER_MESSAGE;
   131 procedure handler_SERVER_MESSAGE;
   156 begin
   132 begin
   157     state.cmd:= cmd_SERVER_MESSAGE;
       
   158 end;
   133 end;
   159 
   134 
   160 procedure handler_SERVER_VARS;
   135 procedure handler_SERVER_VARS;
   161 begin
   136 begin
   162     state.cmd:= cmd_SERVER_VARS;
       
   163 end;
   137 end;
   164 
   138 
   165 procedure handler_TEAM_ACCEPTED;
   139 procedure handler_TEAM_ACCEPTED;
   166 begin
   140 begin
   167     state.cmd:= cmd_TEAM_ACCEPTED;
       
   168 end;
   141 end;
   169 
   142 
   170 procedure handler_TEAM_COLOR;
   143 procedure handler_TEAM_COLOR;
   171 begin
   144 begin
   172     state.cmd:= cmd_TEAM_COLOR;
       
   173 end;
   145 end;
   174 
   146 
   175 procedure handler_WARNING;
   147 procedure handler_WARNING;
   176 begin
   148 begin
   177     state.cmd:= cmd_WARNING;
       
   178 end;
   149 end;
   179 
   150 
   180 procedure handler___UNKNOWN__;
   151 procedure handler___UNKNOWN__;
   181 begin
   152 begin
   182     state.cmd:= cmd___UNKNOWN__;
       
   183 
       
   184     writeln('[NET] Unknown cmd');
   153     writeln('[NET] Unknown cmd');
   185 end;
   154 end;
   186 
   155 
   187 const handlers: array[0..28] of PHandler = (@handler___UNKNOWN__, @handler_WARNING, @handler_TEAM_COLOR, @handler_TEAM_ACCEPTED, @handler_SERVER_VARS, @handler_SERVER_MESSAGE, @handler_SERVER_AUTH, @handler_RUN_GAME, @handler_ROUND_FINISHED, @handler_ROOMS, @handler_PROTO, @handler_PING, @handler_NOTICE, @handler_NICK, @handler_LOBBY_LEFT, @handler_LOBBY_JOINED, @handler_LEFT, @handler_KICKED, @handler_JOINING, @handler_JOINED, @handler_INFO, @handler_HH_NUM, @handler_EM, @handler_CONNECTED, @handler_CLIENT_FLAGS, @handler_CHAT, @handler_BYE, @handler_BANLIST, @handler_ASKPASSWORD);
   156 const handlers: array[0..28] of PHandler = (@handler___UNKNOWN__, @handler_WARNING, @handler_TEAM_COLOR, @handler_TEAM_ACCEPTED, @handler_SERVER_VARS, @handler_SERVER_MESSAGE, @handler_SERVER_AUTH, @handler_RUN_GAME, @handler_ROUND_FINISHED, @handler_ROOMS, @handler_PROTO, @handler_PING, @handler_NOTICE, @handler_NICK, @handler_LOBBY_LEFT, @handler_LOBBY_JOINED, @handler_LEFT, @handler_KICKED, @handler_JOINING, @handler_JOINED, @handler_INFO, @handler_HH_NUM, @handler_EM, @handler_CONNECTED, @handler_CLIENT_FLAGS, @handler_CHAT, @handler_BYE, @handler_BANLIST, @handler_ASKPASSWORD);
   188 
   157 
   203         until (c = #0) or (c = #10);
   172         until (c = #0) or (c = #10);
   204     until (c = #0) or (cnt = 1)
   173     until (c = #0) or (cnt = 1)
   205 end;
   174 end;
   206 
   175 
   207 var sock: PTCPSocket;
   176 var sock: PTCPSocket;
   208     fds: PSDLNet_SocketSet;
       
   209     netReaderThread: PSDL_Thread;
   177     netReaderThread: PSDL_Thread;
   210 
   178 
   211 function getCurrChar: char;
   179 function getCurrChar: char;
   212 begin
   180 begin
   213     getCurrChar:= state.buf[state.bufpos]
   181     getCurrChar:= state.buf[state.bufpos]
   234     end;
   202     end;
   235 
   203 
   236     getNextChar:= state.buf[state.bufpos];
   204     getNextChar:= state.buf[state.bufpos];
   237 end;
   205 end;
   238 
   206 
       
   207 function netWriter(sock: PTCPSocket): LongInt; cdecl; export;
       
   208 begin
       
   209     netWriter:= 0;
       
   210 end;
       
   211 
   239 function netReader(data: pointer): LongInt; cdecl; export;
   212 function netReader(data: pointer): LongInt; cdecl; export;
   240 var c: char;
   213 var c: char;
   241 begin
   214     ipaddr: TIPAddress;
   242 repeat
   215 begin
   243     c:= getNextChar;
   216     netReader:= 0;
   244     writeln('>>>>> ', c, ' [', letters[state.l], '] ', commands[state.l]);
   217 
   245     if c = #0 then
   218     if SDLNet_ResolveHost(ipaddr, PChar('netserver.hedgewars.org'), 46631) = 0 then
   246         state.netState:= netDisconnected
   219         sock:= SDLNet_TCP_Open(ipaddr);
   247     else
   220 
   248     begin
   221     SDL_CreateThread(@netWriter{$IFDEF SDL2}, 'netWriter'{$ENDIF}, sock);
   249         while (letters[state.l] <> c) and (commands[state.l] > 0) do
   222 
   250             inc(state.l, commands[state.l]);
   223     repeat
   251 
   224         c:= getNextChar;
   252         if c = letters[state.l] then
   225         //writeln('>>>>> ', c, ' [', letters[state.l], '] ', commands[state.l]);
   253             if commands[state.l] < 0 then
   226         if c = #0 then
       
   227             state.netState:= netDisconnected
       
   228         else
       
   229         begin
       
   230             while (letters[state.l] <> c) and (commands[state.l] > 0) do
       
   231                 inc(state.l, commands[state.l]);
       
   232 
       
   233             if c = letters[state.l] then
       
   234                 if commands[state.l] < 0 then
   254                 begin
   235                 begin
       
   236                     state.cmd:= TCmdType(-10 - commands[state.l]);
       
   237                     writeln('[NET] ', state.cmd);
   255                     handlers[-10 - commands[state.l]]();
   238                     handlers[-10 - commands[state.l]]();
   256                     handleTail()
   239                     handleTail()
   257                 end
   240                 end
       
   241                 else
       
   242                     inc(state.l)
   258             else
   243             else
   259                 inc(state.l)
   244             begin
   260         else
   245                 handler___UNKNOWN__();
   261         begin
   246                 handleTail()
   262             handler___UNKNOWN__();
   247             end
   263             handleTail()
       
   264         end
   248         end
   265     end
   249     until state.netState = netDisconnected;
   266 until state.netState = netDisconnected;
   250 
   267 
   251     sock:= nil;
   268 writeln('[NET] netReader: disconnected');
   252 
       
   253     writeln('[NET] netReader: disconnected');
   269 end;
   254 end;
   270 
   255 
   271 procedure sendNet(s: shortstring);
   256 procedure sendNet(s: shortstring);
   272 begin
   257 begin
   273     writeln('[NET] Send: ', s);
   258     writeln('[NET] Send: ', s);
   274     SDLNet_TCP_Send(sock, @s[1], byte(s[0]));
   259     SDLNet_TCP_Send(sock, @s[1], byte(s[0]));
   275     SDLNet_TCP_Send(sock, @endCmd, 2);
   260     SDLNet_TCP_Send(sock, @endCmd, 2);
   276 end;
   261 end;
   277 
   262 
   278 procedure connectOfficialServer;
   263 procedure connectOfficialServer;
   279 var ipaddr: TIPAddress;
       
   280 begin
   264 begin
   281     if sock <> nil then
   265     if sock <> nil then
   282         exit;
   266         exit;
   283 
   267 
   284     if SDLNet_ResolveHost(ipaddr, PChar('netserver.hedgewars.org'), 46631) = 0 then
       
   285         sock:= SDLNet_TCP_Open(ipaddr);
       
   286 
       
   287     state.bufpos:= 0;
   268     state.bufpos:= 0;
   288     state.buf:= '';
   269     state.buf:= '';
   289 
   270 
   290     state.l:= 0;
   271     state.l:= 0;
   291     state.netState:= netConnecting;
   272     state.netState:= netConnecting;
   296 procedure initModule;
   277 procedure initModule;
   297 begin
   278 begin
   298     sock:= nil;
   279     sock:= nil;
   299 
   280 
   300     SDLNet_Init;
   281     SDLNet_Init;
   301     fds:= SDLNet_AllocSocketSet(1);
       
   302 end;
   282 end;
   303 
   283 
   304 procedure freeModule;
   284 procedure freeModule;
   305 begin
   285 begin
   306 end;
   286 end;