1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: net_channel_player.cpp 3892 2008-12-17 19:27:17Z dj_jl $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "gamedefs.h"
29 #include "network.h"
30
31 // MACROS ------------------------------------------------------------------
32
33 // TYPES -------------------------------------------------------------------
34
35 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
36
37 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38
39 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40
41 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
42
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
44
45 // PRIVATE DATA DEFINITIONS ------------------------------------------------
46
47 // CODE --------------------------------------------------------------------
48
49 //==========================================================================
50 //
51 // VPlayerChannel::VPlayerChannel
52 //
53 //==========================================================================
54
VPlayerChannel(VNetConnection * AConnection,vint32 AIndex,vuint8 AOpenedLocally)55 VPlayerChannel::VPlayerChannel(VNetConnection* AConnection, vint32 AIndex,
56 vuint8 AOpenedLocally)
57 : VChannel(AConnection, CHANNEL_Player, AIndex, AOpenedLocally)
58 , Plr(NULL)
59 , OldData(NULL)
60 , NewObj(false)
61 , FieldCondValues(NULL)
62 {
63 }
64
65 //==========================================================================
66 //
67 // VPlayerChannel::~VPlayerChannel
68 //
69 //==========================================================================
70
~VPlayerChannel()71 VPlayerChannel::~VPlayerChannel()
72 {
73 SetPlayer(NULL);
74 }
75
76 //==========================================================================
77 //
78 // VPlayerChannel::SetPlayer
79 //
80 //==========================================================================
81
SetPlayer(VBasePlayer * APlr)82 void VPlayerChannel::SetPlayer(VBasePlayer* APlr)
83 {
84 guard(VPlayerChannel::SetPlayer);
85 if (Plr)
86 {
87 if (OldData)
88 {
89 for (VField* F = Plr->GetClass()->NetFields; F; F = F->NextNetField)
90 {
91 VField::DestructField(OldData + F->Ofs, F->Type);
92 }
93 delete[] OldData;
94 OldData = NULL;
95 }
96 if (FieldCondValues)
97 {
98 delete[] FieldCondValues;
99 FieldCondValues = NULL;
100 }
101 }
102
103 Plr = APlr;
104
105 if (Plr)
106 {
107 VBasePlayer* Def = (VBasePlayer*)Plr->GetClass()->Defaults;
108 OldData = new vuint8[Plr->GetClass()->ClassSize];
109 memset(OldData, 0, Plr->GetClass()->ClassSize);
110 for (VField* F = Plr->GetClass()->NetFields; F; F = F->NextNetField)
111 {
112 VField::CopyFieldValue((vuint8*)Def + F->Ofs, OldData + F->Ofs,
113 F->Type);
114 }
115 FieldCondValues = new vuint8[Plr->GetClass()->NumNetFields];
116 NewObj = true;
117 }
118 unguard;
119 }
120
121 //==========================================================================
122 //
123 // VPlayerChannel::EvalCondValues
124 //
125 //==========================================================================
126
EvalCondValues(VObject * Obj,VClass * Class,vuint8 * Values)127 void VPlayerChannel::EvalCondValues(VObject* Obj, VClass* Class, vuint8* Values)
128 {
129 guard(VPlayerChannel::EvalCondValues);
130 if (Class->GetSuperClass())
131 {
132 EvalCondValues(Obj, Class->GetSuperClass(), Values);
133 }
134 for (int i = 0; i < Class->RepInfos.Num(); i++)
135 {
136 P_PASS_REF(Obj);
137 bool Val = !!VObject::ExecuteFunction(Class->RepInfos[i].Cond).i;
138 for (int j = 0; j < Class->RepInfos[i].RepFields.Num(); j++)
139 {
140 if (Class->RepInfos[i].RepFields[j].Member->MemberType != MEMBER_Field)
141 continue;
142 Values[((VField*)Class->RepInfos[i].RepFields[j].Member)->NetIndex] = Val;
143 }
144 }
145 unguard;
146 }
147
148 //==========================================================================
149 //
150 // VPlayerChannel::Update
151 //
152 //==========================================================================
153
Update()154 void VPlayerChannel::Update()
155 {
156 guard(VPlayerChannel::Update);
157 EvalCondValues(Plr, Plr->GetClass(), FieldCondValues);
158
159 VMessageOut Msg(this);
160 Msg.bReliable = true;
161 vuint8* Data = (vuint8*)Plr;
162 for (VField* F = Plr->GetClass()->NetFields; F; F = F->NextNetField)
163 {
164 if (!FieldCondValues[F->NetIndex])
165 {
166 continue;
167 }
168 if (VField::IdenticalValue(Data + F->Ofs, OldData + F->Ofs, F->Type))
169 {
170 continue;
171 }
172 if (F->Type.Type == TYPE_Array)
173 {
174 VFieldType IntType = F->Type;
175 IntType.Type = F->Type.ArrayInnerType;
176 int InnerSize = IntType.GetSize();
177 for (int i = 0; i < F->Type.ArrayDim; i++)
178 {
179 if (VField::IdenticalValue(Data + F->Ofs + i * InnerSize,
180 OldData + F->Ofs + i * InnerSize, IntType))
181 {
182 continue;
183 }
184 Msg.WriteInt(F->NetIndex, Plr->GetClass()->NumNetFields);
185 Msg.WriteInt(i, F->Type.ArrayDim);
186 if (VField::NetSerialiseValue(Msg, Connection->ObjMap,
187 Data + F->Ofs + i * InnerSize, IntType))
188 {
189 VField::CopyFieldValue(Data + F->Ofs + i * InnerSize,
190 OldData + F->Ofs + i * InnerSize, IntType);
191 }
192 }
193 }
194 else
195 {
196 Msg.WriteInt(F->NetIndex, Plr->GetClass()->NumNetFields);
197 if (VField::NetSerialiseValue(Msg, Connection->ObjMap,
198 Data + F->Ofs, F->Type))
199 {
200 VField::CopyFieldValue(Data + F->Ofs, OldData + F->Ofs,
201 F->Type);
202 }
203 }
204 }
205
206 if (Msg.GetNumBits())
207 {
208 SendMessage(&Msg);
209 }
210 unguard;
211 }
212
213 //==========================================================================
214 //
215 // VPlayerChannel::ParsePacket
216 //
217 //==========================================================================
218
ParsePacket(VMessageIn & Msg)219 void VPlayerChannel::ParsePacket(VMessageIn& Msg)
220 {
221 guard(VPlayerChannel::ParsePacket);
222 while (!Msg.AtEnd())
223 {
224 int FldIdx = Msg.ReadInt(Plr->GetClass()->NumNetFields);
225 VField* F = NULL;
226 for (VField* CF = Plr->GetClass()->NetFields; CF; CF = CF->NextNetField)
227 {
228 if (CF->NetIndex == FldIdx)
229 {
230 F = CF;
231 break;
232 }
233 }
234 if (F)
235 {
236 if (F->Type.Type == TYPE_Array)
237 {
238 int Idx = Msg.ReadInt(F->Type.ArrayDim);
239 VFieldType IntType = F->Type;
240 IntType.Type = F->Type.ArrayInnerType;
241 VField::NetSerialiseValue(Msg, Connection->ObjMap,
242 (vuint8*)Plr + F->Ofs + Idx * IntType.GetSize(), IntType);
243 }
244 else
245 {
246 VField::NetSerialiseValue(Msg, Connection->ObjMap,
247 (vuint8*)Plr + F->Ofs, F->Type);
248 }
249 continue;
250 }
251
252 if (ReadRpc(Msg, FldIdx, Plr))
253 {
254 continue;
255 }
256
257 Sys_Error("Bad net field %d", FldIdx);
258 }
259 unguard;
260 }
261