hedgewars/uFLNetProtocol.pas
branchqmlfrontend
changeset 12861 95d903b976d0
parent 12860 1b2b84315d27
child 12862 90f927b4b9e1
equal deleted inserted replaced
12860:1b2b84315d27 12861:95d903b976d0
     1 unit uFLNetProtocol;
       
     2 interface
       
     3 
       
     4 procedure passNetData(p: pointer); cdecl;
       
     5 
       
     6 procedure sendChatLine(msg: PChar); cdecl;
       
     7 procedure joinRoom(roomName: PChar); cdecl;
       
     8 procedure partRoom(msg: PChar); cdecl;
       
     9 
       
    10 procedure ResetNetState;
       
    11 
       
    12 implementation
       
    13 uses uFLNetTypes, uFLTypes, uFLUICallback, uFLNet, uFLGameConfig, uFLUtils, uFLIPC, uUtils;
       
    14 
       
    15 type
       
    16     PHandler = procedure (var t: TCmdData);
       
    17 
       
    18 var isInRoom: boolean;
       
    19 
       
    20 procedure onRoomLeaving();
       
    21 begin
       
    22     isInRoom:= false;
       
    23     sendUI(mtMoveToLobby, nil, 0);
       
    24     netResetTeams
       
    25 end;
       
    26 
       
    27 var teamIndex: LongInt;
       
    28     tmpTeam: TTeam;
       
    29 
       
    30 const teamFields: array[0..22] of PShortstring = (
       
    31     @tmpTeam.teamName
       
    32     , @tmpTeam.grave
       
    33     , @tmpTeam.fort
       
    34     , @tmpTeam.voice
       
    35     , @tmpTeam.flag
       
    36     , @tmpTeam.owner
       
    37     , nil
       
    38     , @tmpTeam.hedgehogs[0].name
       
    39     , @tmpTeam.hedgehogs[0].hat
       
    40     , @tmpTeam.hedgehogs[1].name
       
    41     , @tmpTeam.hedgehogs[1].hat
       
    42     , @tmpTeam.hedgehogs[2].name
       
    43     , @tmpTeam.hedgehogs[2].hat
       
    44     , @tmpTeam.hedgehogs[3].name
       
    45     , @tmpTeam.hedgehogs[3].hat
       
    46     , @tmpTeam.hedgehogs[4].name
       
    47     , @tmpTeam.hedgehogs[4].hat
       
    48     , @tmpTeam.hedgehogs[5].name
       
    49     , @tmpTeam.hedgehogs[5].hat
       
    50     , @tmpTeam.hedgehogs[6].name
       
    51     , @tmpTeam.hedgehogs[6].hat
       
    52     , @tmpTeam.hedgehogs[7].name
       
    53     , @tmpTeam.hedgehogs[7].hat
       
    54     );
       
    55 
       
    56 procedure handler_ADD_TEAM(var p: TCmdParam);
       
    57 begin
       
    58     teamIndex:= 0;
       
    59     tmpTeam.color:= 0
       
    60 end;
       
    61 
       
    62 procedure handler_ADD_TEAM_s(var s: TCmdParamS);
       
    63 begin
       
    64     if teamIndex = 6 then
       
    65         tmpTeam.botLevel:= strToInt(s.str1)
       
    66     else if teamIndex < 23 then
       
    67         teamFields[teamIndex]^:= s.str1;
       
    68 
       
    69     if teamIndex = 22 then
       
    70         netAddTeam(tmpTeam);
       
    71 
       
    72     inc(teamIndex);
       
    73 end;
       
    74 
       
    75 procedure handler_ASKPASSWORD(var p: TCmdParamS);
       
    76 begin
       
    77 end;
       
    78 
       
    79 procedure handler_BANLIST(var p: TCmdParam);
       
    80 begin
       
    81 end;
       
    82 
       
    83 procedure handler_BANLIST_s(var s: TCmdParamS);
       
    84 begin
       
    85 end;
       
    86 
       
    87 procedure handler_BYE(var p: TCmdParamSL);
       
    88 begin
       
    89     sendUI(mtDisconnected, @p.str2[1], length(p.str2));
       
    90 end;
       
    91 
       
    92 procedure handler_CFG_AMMO(var p: TCmdParamSL);
       
    93 begin
       
    94     netSetAmmo(p.str1, p.str2)
       
    95 end;
       
    96 
       
    97 procedure handler_CFG_DRAWNMAP(var p: TCmdParamL);
       
    98 begin
       
    99     netDrawnData(copy(ansistring(p.str1), 1, p.str1len))
       
   100 end;
       
   101 
       
   102 procedure handler_CFG_FEATURE_SIZE(var p: TCmdParami);
       
   103 begin
       
   104     if isInRoom then
       
   105     begin
       
   106         netSetFeatureSize(p.param1);
       
   107         updatePreviewIfNeeded
       
   108     end;
       
   109 end;
       
   110 
       
   111 var fmcfgIndex: integer;
       
   112 
       
   113 procedure handler_CFG_FULLMAPCONFIG(var p: TCmdParam);
       
   114 begin
       
   115     fmcfgIndex:= 0;
       
   116 end;
       
   117 
       
   118 procedure handler_CFG_FULLMAPCONFIG_s(var s: TCmdParamS);
       
   119 begin
       
   120     if not isInRoom then exit;
       
   121 
       
   122     inc(fmcfgIndex);
       
   123     case fmcfgIndex of
       
   124         1: netSetFeatureSize(strToInt(s.str1));
       
   125         2: if s.str1[0] <> '+' then netSetMap(s.str1);
       
   126         3: netSetMapGen(strToInt(s.str1));
       
   127         4: netSetMazeSize(strToInt(s.str1));
       
   128         5: netSetSeed(s.str1);
       
   129         6: begin
       
   130                 netSetTemplate(strToInt(s.str1));
       
   131                 updatePreviewIfNeeded;
       
   132             end;
       
   133     end;
       
   134 end;
       
   135 
       
   136 procedure handler_CFG_MAP(var p: TCmdParamS);
       
   137 begin
       
   138     if isInRoom then
       
   139         netSetMap(p.str1);
       
   140 end;
       
   141 
       
   142 procedure handler_CFG_MAPGEN(var p: TCmdParami);
       
   143 begin
       
   144     if isInRoom then
       
   145     begin
       
   146         netSetMapGen(p.param1);
       
   147         updatePreviewIfNeeded
       
   148     end
       
   149 end;
       
   150 
       
   151 procedure handler_CFG_MAZE_SIZE(var p: TCmdParami);
       
   152 begin
       
   153     if isInRoom then
       
   154     begin
       
   155         netSetMazeSize(p.param1);
       
   156         updatePreviewIfNeeded
       
   157     end
       
   158 end;
       
   159 
       
   160 var schemeIndex: LongInt;
       
   161     tmpScheme: TScheme;
       
   162 
       
   163 procedure handler_CFG_SCHEME(var p: TCmdParam);
       
   164 begin
       
   165     schemeIndex:= 0
       
   166 end;
       
   167 
       
   168 const schemeFields: array[0..43] of pointer = (
       
   169       @tmpScheme.schemeName          //  0
       
   170     , @tmpScheme.fortsmode           //  1
       
   171     , @tmpScheme.divteams            //  2
       
   172     , @tmpScheme.solidland           //  3
       
   173     , @tmpScheme.border              //  4
       
   174     , @tmpScheme.lowgrav             //  5
       
   175     , @tmpScheme.laser               //  6
       
   176     , @tmpScheme.invulnerability     //  7
       
   177     , @tmpScheme.resethealth         //  8
       
   178     , @tmpScheme.vampiric            //  9
       
   179     , @tmpScheme.karma               // 10
       
   180     , @tmpScheme.artillery           // 11
       
   181     , @tmpScheme.randomorder         // 12
       
   182     , @tmpScheme.king                // 13
       
   183     , @tmpScheme.placehog            // 14
       
   184     , @tmpScheme.sharedammo          // 15
       
   185     , @tmpScheme.disablegirders      // 16
       
   186     , @tmpScheme.disablelandobjects  // 17
       
   187     , @tmpScheme.aisurvival          // 18
       
   188     , @tmpScheme.infattack           // 19
       
   189     , @tmpScheme.resetweps           // 20
       
   190     , @tmpScheme.perhogammo          // 21
       
   191     , @tmpScheme.disablewind         // 22
       
   192     , @tmpScheme.morewind            // 23
       
   193     , @tmpScheme.tagteam             // 24
       
   194     , @tmpScheme.bottomborder        // 25
       
   195     , @tmpScheme.damagefactor        // 26
       
   196     , @tmpScheme.turntime            // 27
       
   197     , @tmpScheme.health              // 28
       
   198     , @tmpScheme.suddendeath         // 29
       
   199     , @tmpScheme.caseprobability     // 30
       
   200     , @tmpScheme.minestime           // 31
       
   201     , @tmpScheme.minesnum            // 32
       
   202     , @tmpScheme.minedudpct          // 33
       
   203     , @tmpScheme.explosives          // 34
       
   204     , @tmpScheme.airmines            // 35
       
   205     , @tmpScheme.healthprobability   // 36
       
   206     , @tmpScheme.healthcaseamount    // 37
       
   207     , @tmpScheme.waterrise           // 38
       
   208     , @tmpScheme.healthdecrease      // 39
       
   209     , @tmpScheme.ropepct             // 40
       
   210     , @tmpScheme.getawaytime         // 41
       
   211     , @tmpScheme.worldedge           // 42
       
   212     , @tmpScheme.scriptparam         // 43
       
   213    );
       
   214 
       
   215 procedure handler_CFG_SCHEME_s(var s: TCmdParamS);
       
   216 begin
       
   217     if(schemeIndex = 0) then
       
   218         tmpScheme.schemeName:= s.str1
       
   219     else
       
   220     if(schemeIndex = 43) then
       
   221         tmpScheme.scriptparam:= copy(s.str1, 2, length(s.str1) - 1)
       
   222     else
       
   223     if(schemeIndex < 26) then
       
   224         PBoolean(schemeFields[schemeIndex])^:= s.str1[1] = 't'
       
   225     else
       
   226     if(schemeIndex < 43) then
       
   227         PLongInt(schemeFields[schemeIndex])^:= strToInt(s.str1);
       
   228 
       
   229     if(schemeIndex = 43) then
       
   230         netSetScheme(tmpScheme);
       
   231 
       
   232     inc(schemeIndex);
       
   233 end;
       
   234 
       
   235 procedure handler_CFG_SCRIPT(var p: TCmdParamS);
       
   236 begin
       
   237     if isInRoom then
       
   238         netSetScript(p.str1)
       
   239 end;
       
   240 
       
   241 procedure handler_CFG_SEED(var p: TCmdParamS);
       
   242 begin
       
   243     if isInRoom then
       
   244         netSetSeed(p.str1)
       
   245 end;
       
   246 
       
   247 procedure handler_CFG_TEMPLATE(var p: TCmdParami);
       
   248 begin
       
   249     if isInRoom then
       
   250     begin
       
   251         netSetTemplate(p.param1);
       
   252         updatePreviewIfNeeded
       
   253     end
       
   254 end;
       
   255 
       
   256 procedure handler_CFG_THEME(var p: TCmdParamS);
       
   257 begin
       
   258     if isInRoom then
       
   259         netSetTheme(p.str1)
       
   260 end;
       
   261 
       
   262 procedure handler_CHAT(var p: TCmdParamSL);
       
   263 var s: string;
       
   264 begin
       
   265     s:= p.str1 + #10 + copy(p.str2, 0, p.str2len);
       
   266     if isInRoom then
       
   267         sendUI(mtRoomChatLine, @s[1], length(s))
       
   268     else
       
   269         sendUI(mtLobbyChatLine, @s[1], length(s));
       
   270 end;
       
   271 
       
   272 var flags: array[TClientFlag] of LongInt;
       
   273     isFlagsLine: boolean;
       
   274 procedure handler_CLIENT_FLAGS(var p: TCmdParamS);
       
   275 var f: TClientFlag;
       
   276 begin
       
   277     for f:= Low(TClientFlag) to High(TClientFlag) do
       
   278         flags[f]:= 0;
       
   279 
       
   280     isFlagsLine:= true;
       
   281 end;
       
   282 
       
   283 procedure handler_CLIENT_FLAGS_s(var s: TCmdParamS);
       
   284 var isRemoval: boolean;
       
   285     flagValue, i: LongInt;
       
   286 begin
       
   287     if isFlagsLine then
       
   288     begin
       
   289         if s.str1[1] = '+' then flagValue:= 1 else flagValue:= -1;
       
   290         for i:= 2 to Length(s.str1) do
       
   291             case s.str1[1] of
       
   292                 'r': flags[cfReady]:= flagValue;
       
   293                 'u': flags[cfRegistered]:= flagValue;
       
   294                 'i': flags[cfInRoom]:= flagValue;
       
   295                 'c': flags[cfContributor]:= flagValue;
       
   296                 'g': flags[cfInGame]:= flagValue;
       
   297                 'h': flags[cfRoomAdmin]:= flagValue;
       
   298                 'a': flags[cfServerAdmin]:= flagValue;
       
   299             end;
       
   300 
       
   301         isFlagsLine:= false;
       
   302     end else
       
   303     begin
       
   304 
       
   305     end
       
   306 end;
       
   307 
       
   308 procedure handler_CONNECTED(var p: TCmdParami);
       
   309 begin
       
   310     sendUI(mtConnected, nil, 0);
       
   311     //writeln('Server features version ', p.param1);
       
   312     sendNet('PROTO' + #10 + '52');
       
   313     sendNet('NICK' + #10 + myNickname);
       
   314 end;
       
   315 
       
   316 procedure handler_EM(var p: TCmdParam);
       
   317 begin
       
   318 end;
       
   319 
       
   320 procedure handler_EM_s(var p: TCmdParamL);
       
   321 var i, l: Longword;
       
   322     s: shortstring;
       
   323 begin
       
   324     i:= 1;
       
   325     l:= length(p.str1);
       
   326 
       
   327     while i < l do
       
   328     begin
       
   329         s:= DecodeBase64(copy(p.str1, i, 240));
       
   330         ipcToEngineRaw(@s[1], byte(s[0]));
       
   331         inc(i, 160)
       
   332     end;
       
   333 end;
       
   334 
       
   335 procedure handler_ERROR(var p: TCmdParamL);
       
   336 begin
       
   337     sendUI(mtError, @p.str1[1], length(p.str1));
       
   338 end;
       
   339 
       
   340 procedure handler_HH_NUM(var p: TCmdParamSS);
       
   341 begin
       
   342     netSetHedgehogsNumber(p.str1, StrToInt(p.str2))
       
   343 end;
       
   344 
       
   345 procedure handler_INFO(var p: TCmdParam);
       
   346 begin
       
   347 end;
       
   348 
       
   349 procedure handler_INFO_s(var s: TCmdParamS);
       
   350 begin
       
   351 end;
       
   352 
       
   353 procedure handler_JOINED(var p: TCmdParam);
       
   354 begin
       
   355 end;
       
   356 
       
   357 procedure handler_JOINED_s(var s: TCmdParamS);
       
   358 begin
       
   359     if s.str1 = myNickname then // we joined a room
       
   360     begin
       
   361         isInRoom:= true;
       
   362         sendUI(mtMoveToRoom, nil, 0);
       
   363     end;
       
   364 
       
   365     sendUI(mtAddRoomClient, @s.str1[1], length(s.str1));
       
   366 end;
       
   367 
       
   368 procedure handler_JOINING(var p: TCmdParamS);
       
   369 begin
       
   370 end;
       
   371 
       
   372 procedure handler_KICKED(var p: TCmdParam);
       
   373 begin
       
   374     onRoomLeaving()
       
   375 end;
       
   376 
       
   377 procedure handler_LEFT(var p: TCmdParamSL);
       
   378 var s: string;
       
   379 begin
       
   380     s:= p.str1 + #10 + copy(p.str2, 0, p.str2len);
       
   381     sendUI(mtRemoveRoomClient, @s[1], length(s));
       
   382 end;
       
   383 
       
   384 procedure handler_LOBBY_JOINED(var p: TCmdParam);
       
   385 begin
       
   386 end;
       
   387 
       
   388 procedure handler_LOBBY_JOINED_s(var s: TCmdParamS);
       
   389 begin
       
   390     if s.str1 = myNickname then
       
   391     begin
       
   392         sendUI(mtMoveToLobby, nil, 0);
       
   393         sendNet('LIST');
       
   394     end;
       
   395 
       
   396     sendUI(mtAddLobbyClient, @s.str1[1], length(s.str1));
       
   397 end;
       
   398 
       
   399 procedure handler_LOBBY_LEFT(var p: TCmdParamSL);
       
   400 var s: string;
       
   401 begin
       
   402     s:= p.str1 + #10 + copy(p.str2, 0, p.str2len);
       
   403     sendUI(mtRemoveLobbyClient, @s[1], length(s));
       
   404 end;
       
   405 
       
   406 procedure handler_NICK(var p: TCmdParamS);
       
   407 begin
       
   408     myNickname:= p.str1;
       
   409     sendUI(mtNickname, @p.str1[1], length(p.str1));
       
   410 end;
       
   411 
       
   412 procedure handler_NOTICE(var p: TCmdParamL);
       
   413 begin
       
   414 end;
       
   415 
       
   416 procedure handler_PING(var p: TCmdParam);
       
   417 begin
       
   418     sendNet('PONG')
       
   419 end;
       
   420 
       
   421 procedure handler_PING_s(var s: TCmdParamS);
       
   422 begin
       
   423 end;
       
   424 
       
   425 procedure handler_PROTO(var p: TCmdParami);
       
   426 begin
       
   427     //writeln('Protocol ', p.param1)
       
   428 end;
       
   429 
       
   430 procedure handler_REMOVE_TEAM(var p: TCmdParamS);
       
   431 begin
       
   432     netRemoveTeam(p.str1)
       
   433 end;
       
   434 
       
   435 var roomInfo: string;
       
   436     roomLinesCount: integer;
       
   437 
       
   438 procedure handler_ROOMS(var p: TCmdParam);
       
   439 begin
       
   440     roomInfo:= '';
       
   441     roomLinesCount:= 0
       
   442 end;
       
   443 
       
   444 procedure handler_ROOMS_s(var s: TCmdParamS);
       
   445 begin
       
   446     roomInfo:= roomInfo + s.str1 + #10;
       
   447 
       
   448     if roomLinesCount = 8 then
       
   449     begin
       
   450         sendUI(mtAddRoom, @roomInfo[1], length(roomInfo) - 1);
       
   451         roomLinesCount:= 0;
       
   452         roomInfo:= ''
       
   453     end else inc(roomLinesCount);
       
   454 end;
       
   455 
       
   456 procedure handler_ROOM_ADD(var p: TCmdParam);
       
   457 begin
       
   458     roomInfo:= '';
       
   459     roomLinesCount:= 0
       
   460 end;
       
   461 
       
   462 procedure handler_ROOM_ADD_s(var s: TCmdParamS);
       
   463 begin
       
   464     roomInfo:= roomInfo + s.str1 + #10;
       
   465     inc(roomLinesCount);
       
   466 
       
   467     if roomLinesCount = 9 then
       
   468     begin
       
   469         sendUI(mtAddRoom, @roomInfo[1], length(roomInfo) - 1);
       
   470         roomInfo:= '';
       
   471         roomLinesCount:= 0
       
   472     end;
       
   473 end;
       
   474 
       
   475 procedure handler_ROOM_DEL(var p: TCmdParamS);
       
   476 begin
       
   477     sendUI(mtRemoveRoom, @p.str1[1], length(p.str1));
       
   478 end;
       
   479 
       
   480 procedure handler_ROOM_UPD(var p: TCmdParam);
       
   481 begin
       
   482     roomInfo:= '';
       
   483     roomLinesCount:= 0
       
   484 end;
       
   485 
       
   486 procedure handler_ROOM_UPD_s(var s: TCmdParamS);
       
   487 begin
       
   488     roomInfo:= roomInfo + s.str1 + #10;
       
   489     inc(roomLinesCount);
       
   490 
       
   491     if roomLinesCount = 10 then
       
   492         sendUI(mtUpdateRoom, @roomInfo[1], length(roomInfo) - 1);
       
   493 end;
       
   494 
       
   495 procedure handler_ROUND_FINISHED(var p: TCmdParam);
       
   496 begin
       
   497 end;
       
   498 
       
   499 procedure handler_RUN_GAME(var p: TCmdParam);
       
   500 begin
       
   501     runNetGame
       
   502 end;
       
   503 
       
   504 procedure handler_SERVER_AUTH(var p: TCmdParamS);
       
   505 begin
       
   506 end;
       
   507 
       
   508 procedure handler_SERVER_MESSAGE(var p: TCmdParamL);
       
   509 begin
       
   510 end;
       
   511 
       
   512 procedure handler_SERVER_VARS(var p: TCmdParamSL);
       
   513 begin
       
   514 end;
       
   515 
       
   516 procedure handler_TEAM_ACCEPTED(var p: TCmdParamS);
       
   517 begin
       
   518     netAcceptedTeam(p.str1)
       
   519 end;
       
   520 
       
   521 procedure handler_TEAM_COLOR(var p: TCmdParamSS);
       
   522 begin
       
   523     netSetTeamColor(p.str1, StrToInt(p.str2));
       
   524 end;
       
   525 
       
   526 procedure handler_WARNING(var p: TCmdParamL);
       
   527 begin
       
   528     sendUI(mtWarning, @p.str1[1], length(p.str1));
       
   529 end;
       
   530 
       
   531 const handlers: array[TCmdType] of PHandler = (PHandler(@handler_ADD_TEAM),
       
   532     PHandler(@handler_ADD_TEAM_s), PHandler(@handler_ASKPASSWORD),
       
   533     PHandler(@handler_BANLIST), PHandler(@handler_BANLIST_s),
       
   534     PHandler(@handler_BYE), PHandler(@handler_CFG_AMMO),
       
   535     PHandler(@handler_CFG_DRAWNMAP), PHandler(@handler_CFG_FEATURE_SIZE),
       
   536     PHandler(@handler_CFG_FULLMAPCONFIG), PHandler(@handler_CFG_FULLMAPCONFIG_s),
       
   537     PHandler(@handler_CFG_MAP), PHandler(@handler_CFG_MAPGEN),
       
   538     PHandler(@handler_CFG_MAZE_SIZE), PHandler(@handler_CFG_SCHEME),
       
   539     PHandler(@handler_CFG_SCHEME_s), PHandler(@handler_CFG_SCRIPT),
       
   540     PHandler(@handler_CFG_SEED), PHandler(@handler_CFG_TEMPLATE),
       
   541     PHandler(@handler_CFG_THEME), PHandler(@handler_CHAT),
       
   542     PHandler(@handler_CLIENT_FLAGS), PHandler(@handler_CLIENT_FLAGS_s),
       
   543     PHandler(@handler_CONNECTED), PHandler(@handler_EM), PHandler(@handler_EM_s),
       
   544     PHandler(@handler_ERROR), PHandler(@handler_HH_NUM), PHandler(@handler_INFO),
       
   545     PHandler(@handler_INFO_s), PHandler(@handler_JOINED),
       
   546     PHandler(@handler_JOINED_s), PHandler(@handler_JOINING),
       
   547     PHandler(@handler_KICKED), PHandler(@handler_LEFT),
       
   548     PHandler(@handler_LOBBY_JOINED), PHandler(@handler_LOBBY_JOINED_s),
       
   549     PHandler(@handler_LOBBY_LEFT), PHandler(@handler_NICK),
       
   550     PHandler(@handler_NOTICE), PHandler(@handler_PING), PHandler(@handler_PING_s),
       
   551     PHandler(@handler_PROTO), PHandler(@handler_REMOVE_TEAM),
       
   552     PHandler(@handler_ROOMS), PHandler(@handler_ROOMS_s),
       
   553     PHandler(@handler_ROOM_ADD), PHandler(@handler_ROOM_ADD_s),
       
   554     PHandler(@handler_ROOM_DEL), PHandler(@handler_ROOM_UPD),
       
   555     PHandler(@handler_ROOM_UPD_s), PHandler(@handler_ROUND_FINISHED),
       
   556     PHandler(@handler_RUN_GAME), PHandler(@handler_SERVER_AUTH),
       
   557     PHandler(@handler_SERVER_MESSAGE), PHandler(@handler_SERVER_VARS),
       
   558     PHandler(@handler_TEAM_ACCEPTED), PHandler(@handler_TEAM_COLOR),
       
   559     PHandler(@handler_WARNING));
       
   560 
       
   561 procedure passNetData(p: pointer); cdecl;
       
   562 begin
       
   563     handlers[TCmdData(p^).cmd.cmd](TCmdData(p^))
       
   564 end;
       
   565 
       
   566 procedure sendChatLine(msg: PChar); cdecl;
       
   567 begin
       
   568     sendNetLn('CHAT');
       
   569     sendNet(msg);
       
   570 end;
       
   571 
       
   572 procedure joinRoom(roomName: PChar); cdecl;
       
   573 begin
       
   574     sendNetLn('JOIN_ROOM');
       
   575     sendNet(roomName);
       
   576 end;
       
   577 
       
   578 procedure partRoom(msg: PChar); cdecl;
       
   579 var s: string;
       
   580 begin
       
   581     if isInRoom then
       
   582     begin
       
   583         s:= 'PART';
       
   584         if length(msg) > 0 then
       
   585             s:= s + #10 + msg;
       
   586         sendNet(s);
       
   587 
       
   588         onRoomLeaving()
       
   589     end
       
   590 end;
       
   591 
       
   592 procedure ResetNetState;
       
   593 begin
       
   594     isInRoom:= false;
       
   595 end;
       
   596 
       
   597 end.
       
   598