diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 5e95a6a57dd97b42a4d31178c153e94589092816..01708c297bf82b1d108efa9c427d892e90a29c08 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
NET_MSG_FLAG = 107;
NET_MSG_REQFST = 108;
NET_MSG_GSET = 109;
+ NET_MSG_FLAGPOS= 110;
NET_MSG_PLR = 111;
NET_MSG_PLRPOS = 112;
NET_MSG_ISPAWN = 121;
NET_MSG_IDEL = 122;
+ NET_MSG_IPOS = 123;
NET_MSG_MSPAWN = 131;
NET_MSG_MPOS = 132;
NET_MSG_MSHOT = 134;
NET_MSG_MDEL = 135;
- NET_MSG_PSTATE = 141;
- NET_MSG_PTEX = 142;
+ NET_MSG_PSTATE = 141;
+ NET_MSG_PTEX = 142;
NET_MSG_TSOUND = 151;
NET_MSG_TMUSIC = 152;
NET_CHEAT_SUICIDE = 1;
NET_CHEAT_SPECTATE = 2;
NET_CHEAT_READY = 3;
+ NET_CHEAT_DROPFLAG = 4;
NET_MAX_DIFFTIME = 5000 div 36;
// HOST MESSAGES
+procedure MH_MalformedPacket(C: pTNetClient);
procedure MH_ProcessFirstSpawn (C: pTNetClient);
procedure MH_RECV_Info(C: pTNetClient; var M: TMsg);
procedure MH_SEND_CoopStats(ID: Integer = NET_EVERYONE);
procedure MH_SEND_GameEvent(EvType: Byte; EvNum: Integer = 0; EvStr: string = 'N'; ID: Integer = NET_EVERYONE);
procedure MH_SEND_FlagEvent(EvType: Byte; Flag: Byte; PID: Word; Quiet: Boolean = False; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE);
procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
// PLAYER
procedure MH_SEND_PlayerCreate(PID: Word; ID: Integer = NET_EVERYONE);
@@ -174,6 +179,7 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_
// ITEM
procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
// PANEL
procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE);
procedure MC_RECV_CoopStats(var M: TMsg);
procedure MC_RECV_GameEvent(var M: TMsg);
procedure MC_RECV_FlagEvent(var M: TMsg);
+procedure MC_RECV_FlagPos(var M: TMsg);
procedure MC_RECV_GameSettings(var M: TMsg);
// PLAYER
function MC_RECV_PlayerCreate(var M: TMsg): Word;
// ITEM
procedure MC_RECV_ItemSpawn(var M: TMsg);
procedure MC_RECV_ItemDestroy(var M: TMsg);
+procedure MC_RECV_ItemPos(var M: TMsg);
// PANEL
procedure MC_RECV_PanelTexture(var M: TMsg);
procedure MC_RECV_PanelState(var M: TMsg);
g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF;
const
- NET_KEY_LEFT = 1;
- NET_KEY_RIGHT = 2;
- NET_KEY_UP = 4;
- NET_KEY_DOWN = 8;
- NET_KEY_JUMP = 16;
- NET_KEY_FIRE = 32;
- NET_KEY_OPEN = 64;
- NET_KEY_NW = 256;
- NET_KEY_PW = 512;
- NET_KEY_CHAT = 2048;
- NET_KEY_FORCEDIR = 4096;
+ NET_KEY_LEFT = 1 shl 0;
+ NET_KEY_RIGHT = 1 shl 1;
+ NET_KEY_UP = 1 shl 2;
+ NET_KEY_DOWN = 1 shl 3;
+ NET_KEY_JUMP = 1 shl 4;
+ NET_KEY_FIRE = 1 shl 5;
+ NET_KEY_OPEN = 1 shl 6;
+ NET_KEY_CHAT = 1 shl 7;
+ NET_KEY_FORCEDIR = 1 shl 8;
//var
//kBytePrev: Word = 0;
// GAME
+procedure MH_MalformedPacket(C: pTNetClient);
+begin
+ g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
+ _lc[I_NET_DISC_PROTOCOL]);
+ enet_peer_disconnect(C^.Peer, NET_DISC_PROTOCOL);
+end;
+
procedure MH_RECV_Chat(C: pTNetClient; var M: TMsg);
var
Txt: string;
Mode: Byte;
PID: Word;
Pl: TPlayer;
+ Err: Boolean;
begin
PID := C^.Player;
Pl := g_Player_Get(PID);
- Txt := M.ReadString();
- Mode := M.ReadByte();
+ Err := False;
+ try
+ Txt := M.ReadString();
+ Mode := M.ReadByte();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
+
if (Mode = NET_CHAT_SYSTEM) then
Mode := NET_CHAT_PLAYER; // prevent sending system messages from clients
if (Mode = NET_CHAT_TEAM) and (not gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
var
Ver, PName, Model, Pw: string;
R, G, B, T: Byte;
+ WeapSwitch: Byte;
+ TmpPrefArray: Array [WP_FIRST .. WP_LAST + 1] of Byte;
+ SwitchEmpty: Byte;
+ SkipF: Byte;
PID: Word;
Color: TRGB;
I: Integer;
-begin
- Ver := M.ReadString();
- Pw := M.ReadString();
- PName := M.ReadString();
- Model := M.ReadString();
- R := M.ReadByte();
- G := M.ReadByte();
- B := M.ReadByte();
- T := M.ReadByte();
+ Err: Boolean;
+begin
+ Err := False;
+ try
+ Ver := M.ReadString();
+ Pw := M.ReadString();
+ PName := M.ReadString();
+ Model := M.ReadString();
+ R := M.ReadByte();
+ G := M.ReadByte();
+ B := M.ReadByte();
+ T := M.ReadByte();
+ WeapSwitch := M.ReadByte();
+ for I := WP_FIRST to WP_LAST + 1 do
+ TmpPrefArray[I] := M.ReadByte();
+ SwitchEmpty := M.ReadByte();
+ SkipF := M.ReadByte();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
if Ver <> GAME_VERSION then
begin
Exit;
end;
+ if (C^.Player <> 0) then
+ begin
+ // already received info
+ g_Net_Penalize(C, 'client info spam');
+ Exit;
+ end;
+
Color.R := R;
Color.B := B;
Color.G := G;
with g_Player_Get(PID) do
begin
Name := PName;
+ WeapSwitchMode := WeapSwitch;
+ SetWeaponPrefs(TmpPrefArray);
+ SwitchToEmpty := SwitchEmpty;
+ SkipFist := SkipF;
Reset(True);
end;
C^.Player := PID;
C^.WaitForFirstSpawn := false;
+ C^.AuthTime := 0;
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
e_WriteLog('NET: Client ' + PName + ' [' + IntToStr(C^.ID) +
function MH_RECV_PlayerPos(C: pTNetClient; var M: TMsg): Word;
var
Dir, i: Byte;
+ WeaponAct: Byte;
WeaponSelect: Word;
PID: Word;
kByte: Word;
Pl: TPlayer;
GT: LongWord;
+ Err: Boolean;
begin
Result := 0;
+ Err := False;
if not gGameOn then Exit;
- GT := M.ReadLongWord();
+ try
+ GT := M.ReadLongWord();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
+
PID := C^.Player;
Pl := g_Player_Get(PID);
if Pl = nil then
with Pl do
begin
NetTime := GT;
- kByte := M.ReadWord();
- Dir := M.ReadByte();
- WeaponSelect := M.ReadWord();
+ try
+ kByte := M.ReadWord();
+ Dir := M.ReadByte();
+ WeaponAct := M.ReadByte();
+ WeaponSelect := M.ReadWord();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
+
//e_WriteLog(Format('R:ws=%d', [WeaponSelect]), MSG_WARNING);
if Direction <> TDirection(Dir) then
JustTeleported := False;
if LongBool(kByte and NET_KEY_JUMP) then PressKey(KEY_JUMP, 10000);
if LongBool(kByte and NET_KEY_FIRE) then PressKey(KEY_FIRE, 10000);
if LongBool(kByte and NET_KEY_OPEN) then PressKey(KEY_OPEN, 10000);
- if LongBool(kByte and NET_KEY_NW) then PressKey(KEY_NEXTWEAPON, 10000);
- if LongBool(kByte and NET_KEY_PW) then PressKey(KEY_PREVWEAPON, 10000);
+
+ for i := 0 to 7 do
+ begin
+ if (WeaponAct and Byte(1 shl i)) <> 0 then
+ begin
+ //e_WriteLog(Format(' R:wn=%d', [i]), MSG_WARNING);
+ ProcessWeaponAction(i);
+ end;
+ end;
for i := 0 to 15 do
begin
var
CheatKind: Byte;
Pl: TPlayer;
+ Err: Boolean;
begin
+ Err := False;
Pl := g_Player_Get(C^.Player);
if Pl = nil then Exit;
- CheatKind := M.ReadByte();
+ try
+ CheatKind := M.ReadByte();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
case CheatKind of
NET_CHEAT_SUICIDE:
Dec(gInterReadyCount);
end;
end;
+ NET_CHEAT_DROPFLAG:
+ Pl.TryDropFlag();
end;
end;
TmpModel: string;
TmpColor: TRGB;
TmpTeam: Byte;
+ TmpWeapSwitch: Byte;
+ TmpPrefArray: Array [WP_FIRST .. WP_LAST + 1] of Byte;
+ TmpSwEmpty: Byte;
+ TmpSkipF: Byte;
+ I: Integer;
Pl: TPlayer;
-begin
- TmpName := M.ReadString();
- TmpModel := M.ReadString();
- TmpColor.R := M.ReadByte();
- TmpColor.G := M.ReadByte();
- TmpColor.B := M.ReadByte();
- TmpTeam := M.ReadByte();
+ Err: Boolean;
+begin
+ Err := False;
+ try
+ TmpName := M.ReadString();
+ TmpModel := M.ReadString();
+ TmpColor.R := M.ReadByte();
+ TmpColor.G := M.ReadByte();
+ TmpColor.B := M.ReadByte();
+ TmpTeam := M.ReadByte();
+ TmpWeapSwitch := M.ReadByte();
+ for I := WP_FIRST to WP_LAST + 1 do
+ TmpPrefArray[I] := M.ReadByte();
+ TmpSwEmpty := M.ReadByte();
+ TmpSkipF := M.ReadByte();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
Pl := g_Player_Get(C^.Player);
if Pl = nil then Exit;
if TmpModel <> Pl.Model.Name then
Pl.SetModel(TmpModel);
+ if (TmpWeapSwitch <> Pl.WeapSwitchMode) then
+ Pl.WeapSwitchMode := TmpWeapSwitch;
+
+ Pl.SetWeaponPrefs(TmpPrefArray);
+ if (TmpSwEmpty <> Pl.SwitchToEmpty) then
+ Pl.SwitchToEmpty := TmpSwEmpty;
+
+ if (TmpSkipF <> Pl.SkipFist) then
+ Pl.SkipFist := TmpSkipF;
+
MH_SEND_PlayerSettings(Pl.UID, TmpModel);
end;
procedure MH_RECV_RCONPassword(C: pTNetClient; var M: TMsg);
var
Pwd: string;
+ Err: Boolean;
begin
- Pwd := M.ReadString();
+ Err := False;
+ try
+ Pwd := M.ReadString();
+ except
+ Err := True;
+ end;
+ if Err then begin MH_MalformedPacket(C); Exit; end;
if not NetAllowRCON then Exit;
if Pwd = NetRCONPassword then
begin
procedure MH_RECV_RCONCommand(C: pTNetClient; var M: TMsg);
var
Cmd: string;
+ Err: Boolean;
begin
- Cmd := M.ReadString();
+ Err := False;
+ try
+ Cmd := M.ReadString();
+ except
+ Err := True;
+ end;
+ if Err then begin MH_MalformedPacket(C); Exit; end;
if not NetAllowRCON then Exit;
if not C^.RCONAuth then
begin
Name, Command: string;
Need: Integer;
Pl: TPlayer;
-begin
- Start := M.ReadByte() <> 0;
- Command := M.ReadString();
+ Err: Boolean;
+begin
+ Err := False;
+ try
+ Start := M.ReadByte() <> 0;
+ Command := M.ReadString();
+ except
+ Err := True;
+ end;
+
+ if Err then begin MH_MalformedPacket(C); Exit; end;
Pl := g_Player_Get(C^.Player);
if Pl = nil then Exit;
NetOut.Write(gFlags[Flag].Obj.Y);
NetOut.Write(gFlags[Flag].Obj.Vel.X);
NetOut.Write(gFlags[Flag].Obj.Vel.Y);
+ NetOut.Write(Byte(gFlags[Flag].Direction));
g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
end;
+procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE);
+begin
+ NetOut.Write(Byte(NET_MSG_FLAGPOS));
+ NetOut.Write(Flag);
+ NetOut.Write(gFlags[Flag].Obj.X);
+ NetOut.Write(gFlags[Flag].Obj.Y);
+ NetOut.Write(gFlags[Flag].Obj.Vel.X);
+ NetOut.Write(gFlags[Flag].Obj.Vel.Y);
+
+ g_Net_Host_Send(ID, False, NET_CHAN_IMPORTANT);
+end;
+
procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
begin
NetOut.Write(Byte(NET_MSG_GSET));
if IsKeyPressed(KEY_UP) then kByte := kByte or NET_KEY_UP;
if IsKeyPressed(KEY_DOWN) then kByte := kByte or NET_KEY_DOWN;
if IsKeyPressed(KEY_JUMP) then kByte := kByte or NET_KEY_JUMP;
- if JustTeleported then kByte := kByte or NET_KEY_FORCEDIR;
end;
+ if JustTeleported then kByte := kByte or NET_KEY_FORCEDIR;
+
NetOut.Write(kByte);
if Direction = TDirection.D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
NetOut.Write(GameX);
g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
end;
+procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
+var
+ it: PItem;
+begin
+ it := g_Items_ByIdx(IID);
+
+ NetOut.Write(Byte(NET_MSG_IPOS));
+ NetOut.Write(IID);
+ NetOut.Write(it.Obj.X);
+ NetOut.Write(it.Obj.Y);
+ NetOut.Write(it.Obj.Vel.X);
+ NetOut.Write(it.Obj.Vel.Y);
+
+ g_Net_Host_Send(ID, False, NET_CHAN_LARGEDATA);
+end;
+
// PANEL
procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
if Mode <> NET_CHAT_SYSTEM then
begin
- if Mode = NET_CHAT_PLAYER then
- begin
- g_Console_Add(Txt, True);
- e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
- g_Game_ChatSound(b_Text_Unformat(Txt));
- end else
- if (Mode = NET_CHAT_TEAM) and (gPlayer1 <> nil) then
+ if NetDeafLevel = 0 then
begin
- if gPlayer1.Team = TEAM_RED then
- g_Console_Add(b_Text_Format('\r[Team] ') + Txt, True);
- if gPlayer1.Team = TEAM_BLUE then
- g_Console_Add(b_Text_Format('\b[Team] ') + Txt, True);
- e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
- g_Game_ChatSound(b_Text_Unformat(Txt));
+ if Mode = NET_CHAT_PLAYER then
+ begin
+ g_Console_Add(Txt, True);
+ e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
+ end else
+ if (Mode = NET_CHAT_TEAM) and (gPlayer1 <> nil) then
+ begin
+ if gPlayer1.Team = TEAM_RED then
+ g_Console_Add(b_Text_Format('\r[Team] ') + Txt, True);
+ if gPlayer1.Team = TEAM_BLUE then
+ g_Console_Add(b_Text_Format('\b[Team] ') + Txt, True);
+ e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
+ end;
end;
- end else
+ end else if (NetDeafLevel < 2) then
g_Console_Add(Txt, True);
end;
NET_EV_CHANGE_TEAM:
begin
- if EvNum = TEAM_RED then
- g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_RED], [EvStr]), True);
- if EvNum = TEAM_BLUE then
- g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_BLUE], [EvStr]), True);
+ if NetDeafLevel < 2 then
+ begin
+ if EvNum = TEAM_RED then
+ g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_RED], [EvStr]), True);
+ if EvNum = TEAM_BLUE then
+ g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_BLUE], [EvStr]), True);
+ end;
end;
NET_EV_PLAYER_KICK:
g_Console_Add('*** ' + _lc[I_MESSAGE_LMS_SURVIVOR] + ' ***', True);
NET_EV_BIGTEXT:
- g_Game_Message(AnsiUpperCase(EvStr), Word(EvNum));
+ if NetDeafLevel < 2 then g_Game_Message(AnsiUpperCase(EvStr), Word(EvNum));
NET_EV_SCORE:
begin
end;
end;
+procedure MC_RECV_FlagPos(var M: TMsg);
+var
+ Fl: Byte;
+begin
+ Fl := M.ReadByte();
+ if Fl = FLAG_NONE then Exit;
+ gFlags[Fl].Obj.X := M.ReadLongInt();
+ gFlags[Fl].Obj.Y := M.ReadLongInt();
+ gFlags[Fl].Obj.Vel.X := M.ReadLongInt();
+ gFlags[Fl].Obj.Vel.Y := M.ReadLongInt();
+end;
+
procedure MC_RECV_FlagEvent(var M: TMsg);
var
PID: Word;
gFlags[Fl].Obj.Y := M.ReadLongInt();
gFlags[Fl].Obj.Vel.X := M.ReadLongInt();
gFlags[Fl].Obj.Vel.Y := M.ReadLongInt();
+ gFlags[Fl].Direction := TDirection(M.ReadByte());
Pl := g_Player_Get(PID);
if (Pl = nil) and
end;
end;
- g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
+ if NetDeafLevel < 3 then
+ g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', TMsgType.Notify);
Result := PID;
end;
ReleaseKeys;
- if (kByte = NET_KEY_CHAT) then
+ if LongBool(kByte and NET_KEY_CHAT) then
PressKey(KEY_CHAT, 10000)
else
begin
if LongBool(kByte and NET_KEY_JUMP) then PressKey(KEY_JUMP, 10000);
end;
- if ((Pl <> gPlayer1) and (Pl <> gPlayer2)) or LongBool(kByte and NET_KEY_FORCEDIR) then
+ JustTeleported := LongBool(kByte and NET_KEY_FORCEDIR);
+
+ if ((Pl <> gPlayer1) and (Pl <> gPlayer2)) or JustTeleported then
SetDirection(TDirection(Dir));
GameVelX := M.ReadLongInt();
Result := 0;
if Pl = nil then Exit;
- g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True);
+ if NetDeafLevel < 3 then
+ g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True);
e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', TMsgType.Notify);
g_Player_Remove(PID);
if Pl.Name <> TmpName then
begin
- g_Console_Add(Format(_lc[I_PLAYER_NAME], [Pl.Name, TmpName]), True);
+ if NetDeafLevel < 3 then
+ g_Console_Add(Format(_lc[I_PLAYER_NAME], [Pl.Name, TmpName]), True);
Pl.Name := TmpName;
end;
g_Items_Remove(ID);
end;
+procedure MC_RECV_ItemPos(var M: TMsg);
+var
+ ID: Word;
+ X, Y, VX, VY: Integer;
+ it: PItem;
+begin
+ if not gGameOn then Exit;
+
+ ID := M.ReadWord();
+ X := M.ReadLongInt();
+ Y := M.ReadLongInt();
+ VX := M.ReadLongInt();
+ VY := M.ReadLongInt();
+
+ if g_Items_ValidId(ID) then
+ begin
+ it := g_Items_ByIdx(ID);
+ it.Obj.X := X;
+ it.Obj.Y := Y;
+ it.Obj.Vel.X := VX;
+ it.Obj.Vel.Y := VY;
+ it.positionChanged();
+ end;
+end;
+
// PANEL
procedure MC_RECV_PanelTexture(var M: TMsg);
Str1 := M.ReadString();
Str2 := M.ReadString();
- case EvID of
- NET_VE_STARTED:
- g_Console_Add(Format(_lc[I_MESSAGE_VOTE_STARTED], [Str1, Str2, Int1]), True);
- NET_VE_PASSED:
- g_Console_Add(Format(_lc[I_MESSAGE_VOTE_PASSED], [Str1]), True);
- NET_VE_FAILED:
- g_Console_Add(_lc[I_MESSAGE_VOTE_FAILED], True);
- NET_VE_VOTE:
- g_Console_Add(Format(_lc[I_MESSAGE_VOTE_VOTE], [Str1, Int1, Int2]), True);
- NET_VE_INPROGRESS:
- g_Console_Add(Format(_lc[I_MESSAGE_VOTE_INPROGRESS], [Str1]), True);
- end;
+ if NetDeafLevel < 2 then
+ case EvID of
+ NET_VE_STARTED:
+ g_Console_Add(Format(_lc[I_MESSAGE_VOTE_STARTED], [Str1, Str2, Int1]), True);
+ NET_VE_PASSED:
+ g_Console_Add(Format(_lc[I_MESSAGE_VOTE_PASSED], [Str1]), True);
+ NET_VE_FAILED:
+ g_Console_Add(_lc[I_MESSAGE_VOTE_FAILED], True);
+ NET_VE_VOTE:
+ g_Console_Add(Format(_lc[I_MESSAGE_VOTE_VOTE], [Str1, Int1, Int2]), True);
+ NET_VE_INPROGRESS:
+ g_Console_Add(Format(_lc[I_MESSAGE_VOTE_INPROGRESS], [Str1]), True);
+ end;
end;
// CLIENT SEND
procedure MC_SEND_Info(Password: string);
+var i: Integer;
begin
NetOut.Clear();
NetOut.Write(gPlayer1Settings.Color.G);
NetOut.Write(gPlayer1Settings.Color.B);
NetOut.Write(gPlayer1Settings.Team);
+ NetOut.Write(gPlayer1Settings.WeaponSwitch);
+ for i := WP_FIRST to WP_LAST + 1 do
+ NetOut.Write(gPlayer1Settings.WeaponPreferences[i]);
+ NetOut.Write(gPlayer1Settings.SwitchToEmpty);
+ NetOut.Write(gPlayer1Settings.SkipFist);
g_Net_Client_Send(True, NET_CHAN_SERVICE);
end;
kByte: Word;
Predict: Boolean;
strafeDir: Byte;
+ WeaponAct: Byte = 0;
WeaponSelect: Word = 0;
i: Integer;
begin
end;
if gPlayerAction[0, ACTION_ATTACK] then kByte := kByte or NET_KEY_FIRE;
if gPlayerAction[0, ACTION_ACTIVATE] then kByte := kByte or NET_KEY_OPEN;
- if gPlayerAction[0, ACTION_WEAPNEXT] then kByte := kByte or NET_KEY_NW;
- if gPlayerAction[0, ACTION_WEAPPREV] then kByte := kByte or NET_KEY_PW;
- gPlayerAction[0, ACTION_WEAPNEXT] := False; // HACK, remove after readyweaon&pendinweapon implementation
- gPlayerAction[0, ACTION_WEAPPREV] := False; // HACK, remove after readyweaon&pendinweapon implementation
+ for i := WP_FACT to WP_LACT do
+ begin
+ if gWeaponAction[0, i] then
+ begin
+ WeaponAct := WeaponAct or Byte(1 shl i);
+ gWeaponAction[0, i] := False
+ end
+ end;
for i := WP_FIRST to WP_LAST do
begin
NetOut.Write(gTime);
NetOut.Write(kByte);
NetOut.Write(Byte(gPlayer1.Direction));
+ NetOut.Write(WeaponAct);
NetOut.Write(WeaponSelect);
//e_WriteLog(Format('S:ws=%d', [WeaponSelect]), MSG_WARNING);
g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);
end;
procedure MC_SEND_PlayerSettings();
+var i: Integer;
begin
NetOut.Write(Byte(NET_MSG_PLRSET));
NetOut.Write(gPlayer1Settings.Name);
NetOut.Write(gPlayer1Settings.Color.G);
NetOut.Write(gPlayer1Settings.Color.B);
NetOut.Write(gPlayer1Settings.Team);
+ NetOut.Write(gPlayer1Settings.WeaponSwitch);
+ for i := WP_FIRST to WP_LAST + 1 do
+ NetOut.Write(gPlayer1Settings.WeaponPreferences[i]);
+ NetOut.Write(gPlayer1Settings.SwitchToEmpty);
+ NetOut.Write(gPlayer1Settings.SkipFist);
g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
end;