parent
38529b73c6
commit
a6bb4ac7e2
@ -48,69 +48,86 @@ DEFINE_SPADES_SETTING(cg_unicode, "1");
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
static const char UtfSign = -1;
|
||||
namespace {
|
||||
const char UtfSign = -1;
|
||||
|
||||
enum { BLUE_FLAG = 0, GREEN_FLAG = 1, BLUE_BASE = 2, GREEN_BASE = 3 };
|
||||
enum PacketType {
|
||||
PacketTypePositionData = 0,
|
||||
PacketTypeOrientationData = 1,
|
||||
PacketTypeWorldUpdate = 2,
|
||||
PacketTypeInputData = 3,
|
||||
PacketTypeWeaponInput = 4,
|
||||
PacketTypeHitPacket = 5, // C2S
|
||||
PacketTypeSetHP = 5, // S2C
|
||||
PacketTypeGrenadePacket = 6,
|
||||
PacketTypeSetTool = 7,
|
||||
PacketTypeSetColour = 8,
|
||||
PacketTypeExistingPlayer = 9,
|
||||
PacketTypeShortPlayerData = 10,
|
||||
PacketTypeMoveObject = 11,
|
||||
PacketTypeCreatePlayer = 12,
|
||||
PacketTypeBlockAction = 13,
|
||||
PacketTypeBlockLine = 14,
|
||||
PacketTypeStateData = 15,
|
||||
PacketTypeKillAction = 16,
|
||||
PacketTypeChatMessage = 17,
|
||||
PacketTypeMapStart = 18, // S2C
|
||||
PacketTypeMapChunk = 19, // S2C
|
||||
PacketTypePlayerLeft = 20, // S2P
|
||||
PacketTypeTerritoryCapture = 21, // S2P
|
||||
PacketTypeProgressBar = 22,
|
||||
PacketTypeIntelCapture = 23, // S2P
|
||||
PacketTypeIntelPickup = 24, // S2P
|
||||
PacketTypeIntelDrop = 25, // S2P
|
||||
PacketTypeRestock = 26, // S2P
|
||||
PacketTypeFogColour = 27, // S2C
|
||||
PacketTypeWeaponReload = 28, // C2S2P
|
||||
PacketTypeChangeTeam = 29, // C2S2P
|
||||
PacketTypeChangeWeapon = 30, // C2S2P
|
||||
PacketTypeHandShakeInit = 31, // S2C
|
||||
PacketTypeHandShakeReturn = 32, // C2S
|
||||
PacketTypeVersionGet = 33, // S2C
|
||||
PacketTypeVersionSend = 34, // C2S
|
||||
enum { BLUE_FLAG = 0, GREEN_FLAG = 1, BLUE_BASE = 2, GREEN_BASE = 3 };
|
||||
enum PacketType {
|
||||
PacketTypePositionData = 0,
|
||||
PacketTypeOrientationData = 1,
|
||||
PacketTypeWorldUpdate = 2,
|
||||
PacketTypeInputData = 3,
|
||||
PacketTypeWeaponInput = 4,
|
||||
PacketTypeHitPacket = 5, // C2S
|
||||
PacketTypeSetHP = 5, // S2C
|
||||
PacketTypeGrenadePacket = 6,
|
||||
PacketTypeSetTool = 7,
|
||||
PacketTypeSetColour = 8,
|
||||
PacketTypeExistingPlayer = 9,
|
||||
PacketTypeShortPlayerData = 10,
|
||||
PacketTypeMoveObject = 11,
|
||||
PacketTypeCreatePlayer = 12,
|
||||
PacketTypeBlockAction = 13,
|
||||
PacketTypeBlockLine = 14,
|
||||
PacketTypeStateData = 15,
|
||||
PacketTypeKillAction = 16,
|
||||
PacketTypeChatMessage = 17,
|
||||
PacketTypeMapStart = 18, // S2C
|
||||
PacketTypeMapChunk = 19, // S2C
|
||||
PacketTypePlayerLeft = 20, // S2P
|
||||
PacketTypeTerritoryCapture = 21, // S2P
|
||||
PacketTypeProgressBar = 22,
|
||||
PacketTypeIntelCapture = 23, // S2P
|
||||
PacketTypeIntelPickup = 24, // S2P
|
||||
PacketTypeIntelDrop = 25, // S2P
|
||||
PacketTypeRestock = 26, // S2P
|
||||
PacketTypeFogColour = 27, // S2C
|
||||
PacketTypeWeaponReload = 28, // C2S2P
|
||||
PacketTypeChangeTeam = 29, // C2S2P
|
||||
PacketTypeChangeWeapon = 30, // C2S2P
|
||||
PacketTypeHandShakeInit = 31, // S2C
|
||||
PacketTypeHandShakeReturn = 32, // C2S
|
||||
PacketTypeVersionGet = 33, // S2C
|
||||
PacketTypeVersionSend = 34, // C2S
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
static std::string EncodeString(std::string str) {
|
||||
auto str2 = CP437::Encode(str, -1);
|
||||
if (!cg_unicode) {
|
||||
// ignore fallbacks
|
||||
return str2;
|
||||
enum class VersionInfoPropertyId : std::uint8_t {
|
||||
ApplicationNameAndVersion = 0,
|
||||
UserLocale = 1,
|
||||
ClientFeatureFlags1 = 2
|
||||
};
|
||||
|
||||
enum class ClientFeatureFlags1 : std::uint32_t { None = 0, SupportsUnicode = 1 << 0 };
|
||||
|
||||
ClientFeatureFlags1 operator|(ClientFeatureFlags1 a, ClientFeatureFlags1 b) {
|
||||
return (ClientFeatureFlags1)((uint32_t)a | (uint32_t)b);
|
||||
}
|
||||
if (str2.find(-1) != std::string::npos) {
|
||||
// some fallbacks; always use UTF8
|
||||
str.insert(0, &UtfSign, 1);
|
||||
} else {
|
||||
str = str2;
|
||||
ClientFeatureFlags1 &operator|=(ClientFeatureFlags1 &a, ClientFeatureFlags1 b) {
|
||||
return a = a | b;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static std::string DecodeString(std::string s) {
|
||||
if (s.size() > 0 && s[0] == UtfSign) {
|
||||
return s.substr(1);
|
||||
std::string EncodeString(std::string str) {
|
||||
auto str2 = CP437::Encode(str, -1);
|
||||
if (!cg_unicode) {
|
||||
// ignore fallbacks
|
||||
return str2;
|
||||
}
|
||||
if (str2.find(-1) != std::string::npos) {
|
||||
// some fallbacks; always use UTF8
|
||||
str.insert(0, &UtfSign, 1);
|
||||
} else {
|
||||
str = str2;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string DecodeString(std::string s) {
|
||||
if (s.size() > 0 && s[0] == UtfSign) {
|
||||
return s.substr(1);
|
||||
}
|
||||
return CP437::Decode(s);
|
||||
}
|
||||
return CP437::Decode(s);
|
||||
}
|
||||
|
||||
class NetPacketReader {
|
||||
@ -197,6 +214,8 @@ namespace spades {
|
||||
return col;
|
||||
}
|
||||
|
||||
std::size_t GetNumRemainingBytes() { return data.size() - pos; }
|
||||
|
||||
std::vector<char> GetData() { return data; }
|
||||
|
||||
std::string ReadData(size_t siz) {
|
||||
@ -298,6 +317,32 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t GetPosition() { return data.size(); }
|
||||
|
||||
void Update(std::size_t position, std::uint8_t newValue) {
|
||||
SPADES_MARK_FUNCTION_DEBUG();
|
||||
|
||||
if (position >= data.size()) {
|
||||
SPRaise("Invalid write (%d should be less than %d)", (int)position,
|
||||
(int)data.size());
|
||||
}
|
||||
|
||||
data[position] = static_cast<char>(newValue);
|
||||
}
|
||||
|
||||
void Update(std::size_t position, std::uint32_t newValue) {
|
||||
SPADES_MARK_FUNCTION_DEBUG();
|
||||
|
||||
if (position + 4 > data.size()) {
|
||||
SPRaise("Invalid write (%d should be less than or equal to %d)",
|
||||
(int)(position + 4), (int)data.size());
|
||||
}
|
||||
|
||||
// Assuming the target platform is little endian and supports
|
||||
// unaligned memory access...
|
||||
*reinterpret_cast<std::uint32_t *>(data.data() + position) = newValue;
|
||||
}
|
||||
|
||||
ENetPacket *CreatePacket(int flag = ENET_PACKET_FLAG_RELIABLE) {
|
||||
return enet_packet_create(data.data(), data.size(), flag);
|
||||
}
|
||||
@ -1402,13 +1447,64 @@ namespace spades {
|
||||
// p->SetWeaponType(wType);
|
||||
} break;
|
||||
case PacketTypeHandShakeInit: SendHandShakeValid(reader.ReadInt()); break;
|
||||
case PacketTypeVersionGet: SendVersion(); break;
|
||||
case PacketTypeVersionGet: {
|
||||
if (reader.GetNumRemainingBytes() > 0) {
|
||||
// Enhanced variant
|
||||
std::set<std::uint8_t> propertyIds;
|
||||
while (reader.GetNumRemainingBytes()) {
|
||||
propertyIds.insert(reader.ReadByte());
|
||||
}
|
||||
SendVersionEnhanced(propertyIds);
|
||||
} else {
|
||||
// Simple variant
|
||||
SendVersion();
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
printf("WARNING: dropped packet %d\n", (int)reader.GetType());
|
||||
reader.DumpDebug();
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::SendVersionEnhanced(const std::set<std::uint8_t> &propertyIds) {
|
||||
NetPacketWriter wri(PacketTypeExistingPlayer);
|
||||
wri.Write((uint8_t)'x');
|
||||
|
||||
for (std::uint8_t propertyId : propertyIds) {
|
||||
wri.Write(propertyId);
|
||||
|
||||
auto lengthLabel = wri.GetPosition();
|
||||
wri.Write((uint8_t)0); // dummy data for "Payload Length"
|
||||
|
||||
auto beginLabel = wri.GetPosition();
|
||||
switch (static_cast<VersionInfoPropertyId>(propertyId)) {
|
||||
case VersionInfoPropertyId::ApplicationNameAndVersion:
|
||||
wri.Write((uint8_t)OpenSpades_VERSION_MAJOR);
|
||||
wri.Write((uint8_t)OpenSpades_VERSION_MINOR);
|
||||
wri.Write((uint8_t)OpenSpades_VERSION_REVISION);
|
||||
wri.Write("OpenSpades");
|
||||
break;
|
||||
case VersionInfoPropertyId::UserLocale:
|
||||
wri.Write(GetCurrentLocaleAndRegion());
|
||||
break;
|
||||
case VersionInfoPropertyId::ClientFeatureFlags1: {
|
||||
auto flags = ClientFeatureFlags1::None;
|
||||
|
||||
if (cg_unicode) {
|
||||
flags |= ClientFeatureFlags1::SupportsUnicode;
|
||||
}
|
||||
|
||||
wri.Write(static_cast<uint32_t>(flags));
|
||||
} break;
|
||||
default:
|
||||
// Just return empty payload for an unrecognized property
|
||||
break;
|
||||
}
|
||||
|
||||
wri.Update(lengthLabel, (uint8_t)(wri.GetPosition() - beginLabel));
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::SendJoin(int team, WeaponType weapType, std::string name, int kills) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
int weapId;
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cstdint>
|
||||
|
||||
#include "PhysicsConstants.h"
|
||||
#include "Player.h"
|
||||
@ -115,6 +117,9 @@ namespace spades {
|
||||
std::string DisconnectReasonString(uint32_t);
|
||||
|
||||
void MapLoaded();
|
||||
|
||||
void SendVersion();
|
||||
void SendVersionEnhanced(const std::set<std::uint8_t> &propertyIds);
|
||||
|
||||
public:
|
||||
NetClient(Client *);
|
||||
@ -147,7 +152,6 @@ namespace spades {
|
||||
void SendWeaponChange(WeaponType);
|
||||
void SendTeamChange(int team);
|
||||
void SendHandShakeValid(int challenge);
|
||||
void SendVersion();
|
||||
|
||||
double GetDownlinkBps() { return bandwidthMonitor->GetDownlinkBps(); }
|
||||
double GetUplinkBps() { return bandwidthMonitor->GetUplinkBps(); }
|
||||
|
@ -1167,14 +1167,27 @@ namespace spades {
|
||||
locale.clear();
|
||||
}
|
||||
|
||||
auto p = std::min(locale.find('_'), locale.find('-'));
|
||||
if (p != std::string::npos) {
|
||||
// The separator must be an underscore
|
||||
locale[p] = '_';
|
||||
}
|
||||
|
||||
currentLocaleRegion = locale;
|
||||
|
||||
auto p = std::min(locale.find('_'), locale.find('-'));
|
||||
if (p != std::string::npos)
|
||||
locale = locale.substr(0, p);
|
||||
currentLocale = locale;
|
||||
}
|
||||
|
||||
std::string GetCurrentLocaleAndRegion() {
|
||||
LoadCurrentLocale();
|
||||
if (currentLocaleRegion.empty()) {
|
||||
return "en_us";
|
||||
}
|
||||
return currentLocaleRegion;
|
||||
}
|
||||
|
||||
static std::shared_ptr<CatalogDomain> GetDomain(const std::string &s) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
@ -313,6 +313,11 @@ namespace spades {
|
||||
extern CatalogDomainHandle defaultDomain;
|
||||
|
||||
void LoadCurrentLocale();
|
||||
|
||||
/**
|
||||
* Returns a current local identifier in this format: `[language[_territory]]`.
|
||||
*/
|
||||
std::string GetCurrentLocaleAndRegion();
|
||||
}
|
||||
|
||||
#define _Tr(...) ::spades::defaultDomain.Get(__VA_ARGS__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user