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