libvwad: updated -- vwadwrite: free file buffers on close (otherwise archive creation...
[k8vavoom.git] / source / net / net_message.cpp
blob57fe750210f6ccf7d0844c7d048193b8dec26b80
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
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.
16 //**
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.
21 //**
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/>.
24 //**
25 //**************************************************************************
26 #include "../gamedefs.h"
27 #include "network.h"
28 #include "net_message.h"
31 //==========================================================================
33 // VMessageIn::toStringDbg
35 //==========================================================================
36 VStr VMessageIn::toStringDbg () const noexcept {
37 return
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)
52 , ChanSequence(0)
53 , PacketId(0)
54 , bOpen(false)
55 , bClose(false)
56 , bReliable(areliable)
57 , Next(nullptr)
58 , Time(0)
59 , bReceivedAck(false)
60 , OutEstimated(0)
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 {
84 ChanType = AChanType;
85 ChanIndex = AChanIndex;
86 ChanSequence = 0;
87 PacketId = 0;
88 bOpen = false;
89 bClose = false;
90 bReliable = areliable;
91 Next = nullptr;
92 Time = 0;
93 bReceivedAck = false;
94 OutEstimated = 0;
98 //==========================================================================
100 // VMessageOut::Reset
102 //==========================================================================
103 void VMessageOut::Reset (VChannel *AChannel, bool areliable) {
104 Clear();
105 SetupWith((AChannel ? AChannel->Type : 0), (AChannel ? AChannel->Index : ~0u), areliable);
110 //==========================================================================
112 // VMessageIn::LoadFrom
114 //==========================================================================
115 bool VMessageIn::LoadFrom (VBitStreamReader &srcPacket) {
116 // clear stream
117 Data.reset();
118 Num = Pos = 0;
119 bError = false;
121 bReliable = srcPacket.ReadBit();
122 bOpen = (bReliable ? srcPacket.ReadBit() : false);
123 bClose = (bReliable ? srcPacket.ReadBit() : false);
124 srcPacket << STRM_INDEX_U(ChanIndex);
125 ChanSequence = 0;
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
135 bError = true;
136 return false;
139 if (srcPacket.IsError()) {
140 GCon->Log(NAME_DevNet, "*** inmessage: incomplete message header");
141 bError = true;
142 return false;
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());
148 bError = true;
149 return false;
152 return !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);
167 if (bReliable) {
168 strm.WriteBit(bOpen);
169 strm.WriteBit(bClose);
170 } else {
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
195 const int bitsize =
196 // header
197 1+ // zero
198 1+ // reliable flag
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
204 // data
205 GetNumBits()+addbits+
206 // stop bit
208 // get size in bytes
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 {
221 return
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);