1 //**************************************************************************
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //**************************************************************************
26 #include "../gamedefs.h"
28 #include "net_message.h"
31 //==========================================================================
33 // VMessageIn::toStringDbg
35 //==========================================================================
36 VStr
VMessageIn::toStringDbg () const noexcept
{
38 va("bits:%5d; open=%d; close=%d; reliable=%d; seq=%u",
39 GetNumBits(), (int)bOpen
, (int)bClose
, (int)bReliable
, ChanSequence
);
43 //==========================================================================
45 // VMessageOut::VMessageOut
47 //==========================================================================
48 VMessageOut::VMessageOut (VChannel
*AChannel
, bool areliable
)
49 : VBitStreamWriter(MAX_MSG_SIZE_BITS
+16, false) // no expand
50 , ChanType(AChannel
? AChannel
->Type
: 0)
51 , ChanIndex(AChannel
? AChannel
->Index
: -1)
56 , bReliable(areliable
)
62 SetupWith((AChannel
? AChannel
->Type
: 0), (AChannel
? AChannel
->Index
: ~0u), areliable
);
66 //==========================================================================
68 // VMessageOut::VMessageOut
70 //==========================================================================
71 VMessageOut::VMessageOut (vuint8 AChanType
, int AChanIndex
, bool areliable
)
72 : VBitStreamWriter(MAX_MSG_SIZE_BITS
+16, false) // no expand
74 SetupWith(AChanType
, (vuint32
)AChanIndex
, areliable
);
78 //==========================================================================
80 // VMessageOut::SetupWith
82 //==========================================================================
83 void VMessageOut::SetupWith (vuint8 AChanType
, int AChanIndex
, bool areliable
) noexcept
{
85 ChanIndex
= AChanIndex
;
90 bReliable
= areliable
;
98 //==========================================================================
100 // VMessageOut::Reset
102 //==========================================================================
103 void VMessageOut::Reset (VChannel
*AChannel
, bool areliable
) {
105 SetupWith((AChannel
? AChannel
->Type
: 0), (AChannel
? AChannel
->Index
: ~0u), areliable
);
110 //==========================================================================
112 // VMessageIn::LoadFrom
114 //==========================================================================
115 bool VMessageIn::LoadFrom (VBitStreamReader
&srcPacket
) {
121 bReliable
= srcPacket
.ReadBit();
122 bOpen
= (bReliable
? srcPacket
.ReadBit() : false);
123 bClose
= (bReliable
? srcPacket
.ReadBit() : false);
124 srcPacket
<< STRM_INDEX_U(ChanIndex
);
126 if (bReliable
) srcPacket
<< STRM_INDEX_U(ChanSequence
);
127 ChanType
= (bReliable
|| bOpen
? srcPacket
.ReadUInt() : 0);
128 vuint32 dataBits
= 0;
129 srcPacket
<< STRM_INDEX_U(dataBits
);
131 if (dataBits
>= (unsigned)srcPacket
.GetNumBits()) {
132 GCon
->Log(NAME_DevNet
, "*** inmessage: invalid number of data bits");
133 srcPacket
.Clear(true);
134 (void)srcPacket
.ReadBit(); // this sets error on srcpacket
139 if (srcPacket
.IsError()) {
140 GCon
->Log(NAME_DevNet
, "*** inmessage: incomplete message header");
145 SetData(srcPacket
, dataBits
);
146 if (srcPacket
.IsError() || IsError()) {
147 GCon
->Logf(NAME_Debug
, "*** inmessage: error reading data from packet (%d : %d)!", (int)srcPacket
.IsError(), (int)IsError());
157 //==========================================================================
159 // VMessageOut::WriteHeader
161 //==========================================================================
162 void VMessageOut::WriteHeader (VBitStreamWriter
&strm
) const {
163 vassert(/*ChanIndex >= 0 &&*/ ChanIndex
< MAX_CHANNELS
);
164 // "normal message" flag
165 strm
.WriteBit(false);
166 strm
.WriteBit(bReliable
);
168 strm
.WriteBit(bOpen
);
169 strm
.WriteBit(bClose
);
171 vassert(!bOpen
&& !bClose
);
173 strm
<< STRM_INDEX_U(ChanIndex
);
174 // for reliable, write channel sequence
175 if (bReliable
) strm
<< STRM_INDEX_U(ChanSequence
);
176 // for reliable or open, write channel type
177 // this is because non-open reliable message can arrive first, and we need to create a channel anyway
178 if (bReliable
|| bOpen
) strm
.WriteUInt(ChanType
);
179 vuint32 dataBits
= (vuint32
)GetNumBits();
180 strm
<< STRM_INDEX_U(dataBits
);
184 //==========================================================================
186 // VMessageOut::EstimateSize
188 // estimate current packet size
189 // channel sequence, and packedid doesn't matter
191 //==========================================================================
192 int VMessageOut::EstimateSizeInBits (int addbits
) const noexcept
{
193 vassert(addbits
>= 0);
194 // this is wrong, because the message should know about communication layer internals; but meh
199 (bReliable
? 2 : 0)+ // open/close flags
200 calcVarIntLength(ChanIndex
)*8+ // channel index
201 (bReliable
? MaxVarIntLength
*8 : 0)+ // channel sequence (unknown yet)
202 (bReliable
|| bOpen
? BitStreamCalcUIntBits(ChanType
) : 0)+ // channel type
203 calcVarIntLength(/*MAX_MSG_SIZE_BITS*/GetNumBits()+addbits
)*8+ // size field
205 GetNumBits()+addbits
+
209 const int bytesize
= (bitsize
+7)>>3;
210 // return resulting bits
211 return (bytesize
<<3);
215 //==========================================================================
217 // VMessageOut::toStringDbg
219 //==========================================================================
220 VStr
VMessageOut::toStringDbg () const noexcept
{
222 va("bits:%5d; pid=%u; seq=%u; open=%d; close=%d; reliable=%d; gotack=%d; time=%u (est:%d)",
223 GetNumBits(), PacketId
, ChanSequence
, (int)bOpen
, (int)bClose
, (int)bReliable
,
224 (int)bReceivedAck
, (unsigned)(Time
*1000), OutEstimated
);