1 /*
2 C-Dogs SDL
3 A port of the legendary (and fun) action/arcade cdogs.
4
5 Copyright (c) 2014-2016, 2020-2021 Cong Xu
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11 Redistributions of source code must retain the above copyright notice, this
12 list of conditions and the following disclaimer.
13 Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
28 */
29 #include "net_util.h"
30
31 #include "proto/nanopb/pb_decode.h"
32 #include "proto/nanopb/pb_encode.h"
33
NetEncode(const GameEventType e,const void * data)34 ENetPacket *NetEncode(const GameEventType e, const void *data)
35 {
36 uint8_t buffer[1024];
37 pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof buffer);
38 const pb_msgdesc_t *fields = GameEventGetEntry(e).Fields;
39 const bool status =
40 (data && fields) ? pb_encode(&stream, fields, data) : true;
41 CASSERT(status, "Failed to encode pb");
42 int msgId = (int)e;
43 ENetPacket *packet = enet_packet_create(
44 &msgId, NET_MSG_SIZE + stream.bytes_written,
45 ENET_PACKET_FLAG_RELIABLE);
46 memcpy(packet->data + NET_MSG_SIZE, buffer, stream.bytes_written);
47 return packet;
48 }
49
NetDecode(ENetPacket * packet,void * dest,const pb_msgdesc_t * fields)50 bool NetDecode(ENetPacket *packet, void *dest, const pb_msgdesc_t *fields)
51 {
52 pb_istream_t stream = pb_istream_from_buffer(
53 packet->data + NET_MSG_SIZE, packet->dataLength - NET_MSG_SIZE);
54 bool status = pb_decode(&stream, fields, dest);
55 CASSERT(status, "Failed to decode pb");
56 return status;
57 }
58
NMakePlayerData(const PlayerData * p)59 NPlayerData NMakePlayerData(const PlayerData *p)
60 {
61 NPlayerData d = NPlayerData_init_default;
62 d.has_Colors = d.has_Stats = d.has_Totals = true;
63 const Character *c = &p->Char;
64 strcpy(d.Name, p->name);
65 strcpy(d.CharacterClass, p->Char.Class->Name);
66 if (p->Char.Hair)
67 {
68 strcpy(d.Hair, p->Char.Hair);
69 }
70 d.Colors = CharColors2Net(c->Colors);
71 d.Weapons_count = MAX_WEAPONS;
72 for (int i = 0; i < (int)d.Weapons_count; i++)
73 {
74 strcpy(d.Weapons[i], p->guns[i] != NULL ? p->guns[i]->name : "");
75 }
76 d.Lives = p->Lives;
77 d.Stats = p->Stats;
78 d.Totals = p->Totals;
79 d.MaxHealth = p->Char.maxHealth;
80 d.LastMission = p->lastMission;
81 d.UID = p->UID;
82 Ammo2Net(&d.Ammo_count, d.Ammo, &p->ammo);
83 return d;
84 }
NMakeCampaignDef(const Campaign * co)85 NCampaignDef NMakeCampaignDef(const Campaign *co)
86 {
87 NCampaignDef def;
88 memset(&def, 0, sizeof def);
89 if (co->Entry.Path)
90 {
91 strcpy((char *)def.Path, co->Entry.Path);
92 }
93 def.GameMode = co->Entry.Mode;
94 def.Mission = co->MissionIndex;
95 return def;
96 }
NMakeMissionComplete(const struct MissionOptions * mo)97 NMissionComplete NMakeMissionComplete(const struct MissionOptions *mo)
98 {
99 NMissionComplete mc;
100 mc.ShowMsg = MissionHasRequiredObjectives(mo);
101 return mc;
102 }
103
Net2Vec2i(const NVec2i v)104 struct vec2i Net2Vec2i(const NVec2i v)
105 {
106 return svec2i(v.x, v.y);
107 }
Vec2i2Net(const struct vec2i v)108 NVec2i Vec2i2Net(const struct vec2i v)
109 {
110 NVec2i nv;
111 nv.x = v.x;
112 nv.y = v.y;
113 return nv;
114 }
NetToVec2(const NVec2 v)115 struct vec2 NetToVec2(const NVec2 v)
116 {
117 return svec2(v.x, v.y);
118 }
Vec2ToNet(const struct vec2 v)119 NVec2 Vec2ToNet(const struct vec2 v)
120 {
121 NVec2 nv;
122 nv.x = v.x;
123 nv.y = v.y;
124 return nv;
125 }
Net2Color(const NColor c)126 color_t Net2Color(const NColor c)
127 {
128 color_t co;
129 co.r = (uint8_t)((c.RGBA & 0xff000000) >> 24);
130 co.g = (uint8_t)((c.RGBA & 0x00ff0000) >> 16);
131 co.b = (uint8_t)((c.RGBA & 0x0000ff00) >> 8);
132 co.a = (uint8_t)(c.RGBA & 0x000000ff);
133 return co;
134 }
Color2Net(const color_t c)135 NColor Color2Net(const color_t c)
136 {
137 NColor co;
138 co.RGBA = (c.r << 24) | (c.g << 16) | (c.b << 8) | c.a;
139 return co;
140 }
CharColors2Net(const CharColors c)141 NCharColors CharColors2Net(const CharColors c)
142 {
143 NCharColors co;
144 co.has_Skin = co.has_Arms = co.has_Body = co.has_Legs = co.has_Hair =
145 co.has_Feet = true;
146 co.Skin = Color2Net(c.Skin);
147 co.Arms = Color2Net(c.Arms);
148 co.Body = Color2Net(c.Body);
149 co.Legs = Color2Net(c.Legs);
150 co.Hair = Color2Net(c.Hair);
151 co.Feet = Color2Net(c.Feet);
152 return co;
153 }
Net2CharColors(const NCharColors c)154 CharColors Net2CharColors(const NCharColors c)
155 {
156 CharColors co;
157 co.Skin = Net2Color(c.Skin);
158 co.Arms = Net2Color(c.Arms);
159 co.Body = Net2Color(c.Body);
160 co.Legs = Net2Color(c.Legs);
161 co.Hair = Net2Color(c.Hair);
162 co.Feet = Net2Color(c.Feet);
163 return co;
164 }
Ammo2Net(pb_size_t * ammoCount,NAmmo * ammo,const CArray * a)165 void Ammo2Net(pb_size_t *ammoCount, NAmmo *ammo, const CArray *a)
166 {
167 *ammoCount = 0;
168 CA_FOREACH(int, amount, *a)
169 if (*amount > 0)
170 {
171 ammo[*ammoCount].Id = _ca_index;
172 ammo[*ammoCount].Amount = *amount;
173 (*ammoCount)++;
174 }
175 CA_FOREACH_END()
176 }
177