mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
sq_getstring and sq_getinteger are now properly implemented (code matches squirrel code, and generated assembly matches that of the game). Adjusted call sites to accommodate the new implementation and added a few extra checks. Also added: * sq_getfloat * sq_getbool * sq_getthread
2300 lines
77 KiB
C++
2300 lines
77 KiB
C++
//=============================================================================//
|
|
//
|
|
// Purpose: ServerGameDLL LiveAPI implementation
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
// TODO:
|
|
// - Add code callback for observer target changed ( event ObserverSwitched )
|
|
// - Add code callback for player weapon switched ( event WeaponSwitched )
|
|
//
|
|
//=============================================================================//
|
|
#include "tier1/depthcounter.h"
|
|
#include "vscript/languages/squirrel_re/include/sqtable.h"
|
|
#include "vscript/languages/squirrel_re/include/sqarray.h"
|
|
#include "game/server/vscript_server.h"
|
|
#include "rtech/liveapi/liveapi.h"
|
|
#include "liveapi.h"
|
|
#include "engine/sys_utils.h"
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4505)
|
|
#include "protoc/events.pb.h"
|
|
#pragma warning(pop)
|
|
|
|
// The total nesting depth cannot exceed this number
|
|
#define LIVEAPI_MAX_ITEM_DEPTH 64
|
|
|
|
|
|
/*
|
|
███████╗██╗ ██╗███████╗███╗ ██╗████████╗ ███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗███████╗
|
|
██╔════╝██║ ██║██╔════╝████╗ ██║╚══██╔══╝ ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██╔════╝
|
|
█████╗ ██║ ██║█████╗ ██╔██╗ ██║ ██║ ██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ ███████╗
|
|
██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║╚██╗██║ ██║ ██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ╚════██║
|
|
███████╗ ╚████╔╝ ███████╗██║ ╚████║ ██║ ██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗███████║
|
|
╚══════╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝
|
|
NOTE: messages are statically allocated to save on runtime overhead, each message is cleared after usage.
|
|
*/
|
|
|
|
static rtech::liveapi::AmmoUsed s_ammoUsed;
|
|
static rtech::liveapi::ArenasItemDeselected s_arenasItemDeselected;
|
|
static rtech::liveapi::ArenasItemSelected s_arenasItemSelected;
|
|
static rtech::liveapi::BannerCollected s_bannerCollected;
|
|
static rtech::liveapi::BlackMarketAction s_blackMarketAction;
|
|
//static rtech::liveapi::ChangeCamera s_changeCamera;
|
|
static rtech::liveapi::CharacterSelected s_characterSelected;
|
|
//static rtech::liveapi::CustomMatch_CreateLobby s_customMatch_CreateLobby;
|
|
//static rtech::liveapi::CustomMatch_GetLobbyPlayers s_customMatch_GetLobbyPlayers;
|
|
//static rtech::liveapi::CustomMatch_GetSettings s_customMatch_GetSettings;
|
|
//static rtech::liveapi::CustomMatch_JoinLobby s_customMatch_JoinLobby;
|
|
//static rtech::liveapi::CustomMatch_KickPlayer s_customMatch_KickPlayer;
|
|
//static rtech::liveapi::CustomMatch_LeaveLobby s_customMatch_LeaveLobby;
|
|
//static rtech::liveapi::CustomMatch_LobbyPlayers s_customMatch_LobbyPlayers;
|
|
//static rtech::liveapi::CustomMatch_SendChat s_customMatch_SendChat;
|
|
//static rtech::liveapi::CustomMatch_SetMatchmaking s_customMatch_SetMatchmaking;
|
|
//static rtech::liveapi::CustomMatch_SetReady s_customMatch_SetReady;
|
|
//static rtech::liveapi::CustomMatch_SetSettings s_customMatch_SetSettings;
|
|
//static rtech::liveapi::CustomMatch_SetTeam s_customMatch_SetTeam;
|
|
//static rtech::liveapi::CustomMatch_SetTeamName s_customMatch_SetTeamName;
|
|
static rtech::liveapi::CustomEvent s_customEvent;
|
|
static rtech::liveapi::GameStateChanged s_gameStateChanged;
|
|
static rtech::liveapi::GibraltarShieldAbsorbed s_gibraltarShieldAbsorbed;
|
|
static rtech::liveapi::GrenadeThrown s_grenadeThrown;
|
|
static rtech::liveapi::Init s_init;
|
|
static rtech::liveapi::InventoryDrop s_inventoryDrop;
|
|
static rtech::liveapi::InventoryPickUp s_inventoryPickUp;
|
|
static rtech::liveapi::InventoryUse s_inventoryUse;
|
|
static rtech::liveapi::LegendUpgradeSelected s_legendUpgradeSelected;
|
|
static rtech::liveapi::LiveAPIEvent s_liveAPIEvent;
|
|
static rtech::liveapi::MatchSetup s_matchSetup;
|
|
static rtech::liveapi::MatchStateEnd s_matchStateEnd;
|
|
static rtech::liveapi::ObserverAnnotation s_observerAnnotation;
|
|
static rtech::liveapi::ObserverSwitched s_observerSwitched;
|
|
//static rtech::liveapi::PauseToggle s_pauseToggle;
|
|
static rtech::liveapi::PlayerAbilityUsed s_playerAbilityUsed;
|
|
static rtech::liveapi::PlayerAssist s_playerAssist;
|
|
static rtech::liveapi::PlayerConnected s_playerConnected;
|
|
static rtech::liveapi::PlayerDamaged s_playerDamaged;
|
|
static rtech::liveapi::PlayerDisconnected s_playerDisconnected;
|
|
static rtech::liveapi::PlayerDowned s_playerDowned;
|
|
static rtech::liveapi::PlayerKilled s_playerKilled;
|
|
static rtech::liveapi::PlayerRespawnTeam s_playerRespawnTeam;
|
|
static rtech::liveapi::PlayerRevive s_playerRevive;
|
|
static rtech::liveapi::PlayerStatChanged s_playerStatChanged;
|
|
static rtech::liveapi::PlayerUpgradeTierChanged s_playerUpgradeTierChanged;
|
|
//static rtech::liveapi::Request s_request;
|
|
//static rtech::liveapi::RequestStatus s_requestStatus;
|
|
//static rtech::liveapi::Response s_response;
|
|
static rtech::liveapi::RevenantForgedShadowDamaged s_revenantForgedShadowDamaged;
|
|
static rtech::liveapi::RingFinishedClosing s_ringFinishedClosing;
|
|
static rtech::liveapi::RingStartClosing s_ringStartClosing;
|
|
static rtech::liveapi::SquadEliminated s_squadEliminated;
|
|
static rtech::liveapi::WarpGateUsed s_warpGateUsed;
|
|
static rtech::liveapi::WeaponSwitched s_weaponSwitched;
|
|
static rtech::liveapi::WraithPortal s_wraithPortal;
|
|
static rtech::liveapi::ZiplineUsed s_ziplineUsed;
|
|
|
|
|
|
/*
|
|
███████╗███╗ ██╗██╗ ██╗███╗ ███╗███████╗██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗███████╗
|
|
██╔════╝████╗ ██║██║ ██║████╗ ████║██╔════╝██╔══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║██╔════╝
|
|
█████╗ ██╔██╗ ██║██║ ██║██╔████╔██║█████╗ ██████╔╝███████║ ██║ ██║██║ ██║██╔██╗ ██║███████╗
|
|
██╔══╝ ██║╚██╗██║██║ ██║██║╚██╔╝██║██╔══╝ ██╔══██╗██╔══██║ ██║ ██║██║ ██║██║╚██╗██║╚════██║
|
|
███████╗██║ ╚████║╚██████╔╝██║ ╚═╝ ██║███████╗██║ ██║██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║███████║
|
|
╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
|
|
NOTE: the values here must align with the enumeration exposed to scripts; see section "abstractions"!
|
|
*/
|
|
|
|
enum class eLiveAPI_EventTypes
|
|
{
|
|
ammoUsed,
|
|
arenasItemDeselected,
|
|
arenasItemSelected,
|
|
|
|
bannerCollected,
|
|
blackMarketAction,
|
|
//changeCamera,
|
|
characterSelected,
|
|
//checkedState,
|
|
//clientState,
|
|
|
|
//customMatch_CreateLobby,
|
|
//customMatch_GetLobbyPlayers,
|
|
//customMatch_GetSettings,
|
|
//customMatch_JoinLobby,
|
|
//customMatch_KickPlayer,
|
|
//customMatch_LeaveLobby,
|
|
//customMatch_LobbyPlayer,
|
|
//customMatch_LobbyPlayers,
|
|
//customMatch_SendChat,
|
|
//customMatch_SetMatchmaking,
|
|
//customMatch_SetReady,
|
|
//customMatch_SetSettings,
|
|
//customMatch_SetTeam,
|
|
//customMatch_SetTeamName,
|
|
customEvent,
|
|
datacenter,
|
|
//gameConVar,
|
|
gameStateChanged,
|
|
gibraltarShieldAbsorbed,
|
|
//globalVars,
|
|
grenadeThrown,
|
|
init,
|
|
|
|
inventoryDrop,
|
|
inventoryItem,
|
|
inventoryPickUp,
|
|
inventoryUse,
|
|
|
|
legendUpgradeSelected,
|
|
liveAPIEvent,
|
|
loadoutConfiguration,
|
|
matchSetup,
|
|
matchStateEnd,
|
|
observerAnnotation,
|
|
observerSwitched,
|
|
//pauseToggle,
|
|
|
|
player,
|
|
playerAbilityUsed,
|
|
playerAssist,
|
|
playerConnected,
|
|
playerDamaged,
|
|
playerDisconnected,
|
|
playerDowned,
|
|
playerKilled,
|
|
playerRespawnTeam,
|
|
playerRevive,
|
|
playerStatChanged,
|
|
playerUpgradeTierChanged,
|
|
|
|
//request,
|
|
//requestStatus,
|
|
//response,
|
|
|
|
revenantForgedShadowDamaged,
|
|
|
|
ringFinishedClosing,
|
|
ringStartClosing,
|
|
|
|
//runCommand,
|
|
//scriptCall,
|
|
squadEliminated,
|
|
//stateCheck,
|
|
//svcMsgOverflow,
|
|
//svcMsgRemoteScript,
|
|
vector3,
|
|
version,
|
|
warpGateUsed,
|
|
weaponSwitched,
|
|
wraithPortal,
|
|
ziplineUsed,
|
|
};
|
|
|
|
|
|
/*
|
|
██╗ ██╗████████╗██╗██╗ ██╗████████╗██╗ ██╗ ██╗ ███╗ ███╗ █████╗ ██████╗██████╗ ██████╗ ███████╗
|
|
██║ ██║╚══██╔══╝██║██║ ██║╚══██╔══╝╚██╗ ██╔╝ ██║ ████╗ ████║██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔════╝
|
|
██║ ██║ ██║ ██║██║ ██║ ██║ ╚████╔╝ ████████╗ ██╔████╔██║███████║██║ ██████╔╝██║ ██║███████╗
|
|
██║ ██║ ██║ ██║██║ ██║ ██║ ╚██╔╝ ██╔═██╔═╝ ██║╚██╔╝██║██╔══██║██║ ██╔══██╗██║ ██║╚════██║
|
|
╚██████╔╝ ██║ ██║███████╗██║ ██║ ██║ ██████║ ██║ ╚═╝ ██║██║ ██║╚██████╗██║ ██║╚██████╔╝███████║
|
|
╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
|
*/
|
|
|
|
static const char* LiveAPI_EventTypeToString(const eLiveAPI_EventTypes eventType)
|
|
{
|
|
switch (eventType)
|
|
{
|
|
case eLiveAPI_EventTypes::ammoUsed: return "ammoUsed";
|
|
case eLiveAPI_EventTypes::arenasItemDeselected: return "arenasItemDeselected";
|
|
case eLiveAPI_EventTypes::arenasItemSelected: return "arenasItemSelected";
|
|
case eLiveAPI_EventTypes::bannerCollected: return "bannerCollected";
|
|
case eLiveAPI_EventTypes::blackMarketAction: return "blackMarketAction";
|
|
//case eLiveAPI_EventTypes::changeCamera: return "changeCamera";
|
|
case eLiveAPI_EventTypes::characterSelected: return "characterSelected";
|
|
//case eLiveAPI_EventTypes::checkedState: return "checkedState";
|
|
//case eLiveAPI_EventTypes::clientState: return "clientState";
|
|
//case eLiveAPI_EventTypes::customMatch_CreateLobby: return "customMatch_CreateLobby";
|
|
//case eLiveAPI_EventTypes::customMatch_GetLobbyPlayers: return "customMatch_GetLobbyPlayers";
|
|
//case eLiveAPI_EventTypes::customMatch_GetSettings: return "customMatch_GetSettings";
|
|
//case eLiveAPI_EventTypes::customMatch_JoinLobby: return "customMatch_JoinLobby";
|
|
//case eLiveAPI_EventTypes::customMatch_KickPlayer: return "customMatch_KickPlayer";
|
|
//case eLiveAPI_EventTypes::customMatch_LeaveLobby: return "customMatch_LeaveLobby";
|
|
//case eLiveAPI_EventTypes::customMatch_LobbyPlayer: return "customMatch_LobbyPlayer";
|
|
//case eLiveAPI_EventTypes::customMatch_LobbyPlayers: return "customMatch_LobbyPlayers";
|
|
//case eLiveAPI_EventTypes::customMatch_SendChat: return "customMatch_SendChat";
|
|
//case eLiveAPI_EventTypes::customMatch_SetMatchmaking: return "customMatch_SetMatchmaking";
|
|
//case eLiveAPI_EventTypes::customMatch_SetReady: return "customMatch_SetReady";
|
|
//case eLiveAPI_EventTypes::customMatch_SetSettings: return "customMatch_SetSettings";
|
|
//case eLiveAPI_EventTypes::customMatch_SetTeam: return "customMatch_SetTeam";
|
|
//case eLiveAPI_EventTypes::customMatch_SetTeamName: return "customMatch_SetTeamName";
|
|
case eLiveAPI_EventTypes::customEvent: return "customEvent";
|
|
case eLiveAPI_EventTypes::datacenter: return "datacenter";
|
|
//case eLiveAPI_EventTypes::gameConVar: return "gameConVar";
|
|
case eLiveAPI_EventTypes::gameStateChanged: return "gameStateChanged";
|
|
case eLiveAPI_EventTypes::gibraltarShieldAbsorbed: return "gibraltarShieldAbsorbed";
|
|
//case eLiveAPI_EventTypes::globalVars: return "globalVars";
|
|
case eLiveAPI_EventTypes::grenadeThrown: return "grenadeThrown";
|
|
case eLiveAPI_EventTypes::init: return "init";
|
|
case eLiveAPI_EventTypes::inventoryDrop: return "inventoryDrop";
|
|
case eLiveAPI_EventTypes::inventoryItem: return "inventoryItem";
|
|
case eLiveAPI_EventTypes::inventoryPickUp: return "inventoryPickUp";
|
|
case eLiveAPI_EventTypes::inventoryUse: return "inventoryUse";
|
|
case eLiveAPI_EventTypes::legendUpgradeSelected: return "legendUpgradeSelected";
|
|
case eLiveAPI_EventTypes::liveAPIEvent: return "liveAPIEvent";
|
|
case eLiveAPI_EventTypes::loadoutConfiguration: return "loadoutConfiguration";
|
|
case eLiveAPI_EventTypes::matchSetup: return "matchSetup";
|
|
case eLiveAPI_EventTypes::matchStateEnd: return "matchStateEnd";
|
|
case eLiveAPI_EventTypes::observerAnnotation: return "observerAnnotation";
|
|
case eLiveAPI_EventTypes::observerSwitched: return "observerSwitched";
|
|
//case eLiveAPI_EventTypes::pauseToggle: return "pauseToggle";
|
|
case eLiveAPI_EventTypes::player: return "player";
|
|
case eLiveAPI_EventTypes::playerAbilityUsed: return "playerAbilityUsed";
|
|
case eLiveAPI_EventTypes::playerAssist: return "playerAssist";
|
|
case eLiveAPI_EventTypes::playerConnected: return "playerConnected";
|
|
case eLiveAPI_EventTypes::playerDamaged: return "playerDamaged";
|
|
case eLiveAPI_EventTypes::playerDisconnected: return "playerDisconnected";
|
|
case eLiveAPI_EventTypes::playerDowned: return "playerDowned";
|
|
case eLiveAPI_EventTypes::playerKilled: return "playerKilled";
|
|
case eLiveAPI_EventTypes::playerRespawnTeam: return "playerRespawnTeam";
|
|
case eLiveAPI_EventTypes::playerRevive: return "playerRevive";
|
|
case eLiveAPI_EventTypes::playerStatChanged: return "playerStatChanged";
|
|
case eLiveAPI_EventTypes::playerUpgradeTierChanged: return "playerUpgradeTierChanged";
|
|
//case eLiveAPI_EventTypes::request: return "request";
|
|
//case eLiveAPI_EventTypes::requestStatus: return "requestStatus";
|
|
//case eLiveAPI_EventTypes::response: return "response";
|
|
case eLiveAPI_EventTypes::revenantForgedShadowDamaged: return "revenantForgedShadowDamaged";
|
|
case eLiveAPI_EventTypes::ringFinishedClosing: return "ringFinishedClosing";
|
|
case eLiveAPI_EventTypes::ringStartClosing: return "ringStartClosing";
|
|
//case eLiveAPI_EventTypes::runCommand: return "runCommand";
|
|
//case eLiveAPI_EventTypes::scriptCall: return "scriptCall";
|
|
case eLiveAPI_EventTypes::squadEliminated: return "squadEliminated";
|
|
//case eLiveAPI_EventTypes::stateCheck: return "stateCheck";
|
|
//case eLiveAPI_EventTypes::svcMsgOverflow: return "svcMsgOverflow";
|
|
//case eLiveAPI_EventTypes::svcMsgRemoteScript: return "svcMsgRemoteScript";
|
|
case eLiveAPI_EventTypes::vector3: return "vector3";
|
|
case eLiveAPI_EventTypes::version: return "version";
|
|
case eLiveAPI_EventTypes::warpGateUsed: return "warpGateUsed";
|
|
case eLiveAPI_EventTypes::weaponSwitched: return "weaponSwitched";
|
|
case eLiveAPI_EventTypes::wraithPortal: return "wraithPortal";
|
|
case eLiveAPI_EventTypes::ziplineUsed: return "ziplineUsed";
|
|
|
|
default: Assert(0); return "(unknown)";
|
|
};
|
|
}
|
|
|
|
static bool LiveAPI_EnsureType(HSQUIRRELVM const v, const SQObjectPtr& obj, const SQObjectType expectType,
|
|
const google::protobuf::Message* const eventMsg, const SQInteger fieldNum)
|
|
{
|
|
if (sq_type(obj) == expectType)
|
|
return true;
|
|
|
|
const char* const expectTypeName = IdType2Name(expectType);
|
|
const char* const gotTypeName = IdType2Name(sq_type(obj));
|
|
|
|
if (eventMsg)
|
|
{
|
|
const google::protobuf::Descriptor* const descriptor = eventMsg->GetDescriptor();
|
|
|
|
if (fieldNum == -1)
|
|
{
|
|
v_SQVM_RaiseError(v, "Expected type \"%s\", got type \"%s\" for message \"%s\".", expectTypeName, gotTypeName,
|
|
descriptor->name().c_str());
|
|
}
|
|
else
|
|
{
|
|
const google::protobuf::FieldDescriptor* const fieldDescriptor = descriptor->field(fieldNum);
|
|
|
|
v_SQVM_RaiseError(v, "Expected type \"%s\", got type \"%s\" for field \"%s.%s\".", expectTypeName, gotTypeName,
|
|
descriptor->name().c_str(), fieldDescriptor->name().c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v_SQVM_RaiseError(v, "Expected type \"%s\", got type \"%s\".", expectTypeName, gotTypeName);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool LiveAPI_CheckSwitchType(HSQUIRRELVM const v, const SQObjectPtr& obj)
|
|
{
|
|
if (sq_type(obj) == OT_INTEGER)
|
|
return true;
|
|
|
|
v_SQVM_RaiseError(v, "Cannot switch on type \"%s\".", IdType2Name(sq_type(obj)));
|
|
return false;
|
|
}
|
|
|
|
#define LIVEAPI_ENSURE_TYPE(v, obj, expectType, eventMsg, fieldNum) { if (!LiveAPI_EnsureType(v, obj, expectType, eventMsg, fieldNum)) return false; }
|
|
#define LIVEAPI_EMPTY_TABLE_ERROR(v, eventMsg) { v_SQVM_RaiseError(v, "Empty iterable on message \"%s\".", eventMsg->GetTypeName().c_str()); return false; }
|
|
#define LIVEAPI_FIELD_ERROR(v, fieldNum, eventMsg) { v_SQVM_RaiseError(v, "Field \"%d\" doesn't exist in message \"%s\".", fieldNum, eventMsg->GetTypeName().c_str()); return false; }
|
|
#define LIVEAPI_ONEOF_FIELD_ERROR(v, fieldNum, eventMsg) { v_SQVM_RaiseError(v, "Tried to set member \"%d\" of oneof field in message \"%s\" while another has already been set.", fieldNum, eventMsg->GetTypeName().c_str()); return false; }
|
|
#define LIVEAPI_UNSUPPORTED_TYPE_ERROR(v, gotType, eventMsg) {v_SQVM_RaiseError(v, "Value type \"%s\" is not supported for message \"%s\".\n", IdType2Name(gotType), eventMsg->GetTypeName().c_str()); return false; }
|
|
#define LIVEAPI_CHECK_RECURSION_DEPTH(v, currDepth) { if (currDepth > LIVEAPI_MAX_ITEM_DEPTH) { v_SQVM_RaiseError(v, "Exceeded nesting depth limit of \"%i\".", LIVEAPI_MAX_ITEM_DEPTH); return false; }}
|
|
|
|
|
|
/*
|
|
██╗███╗ ██╗████████╗███████╗██████╗ ███╗ ███╗███████╗██████╗ ██╗ █████╗ ██████╗ ██╗ ██╗
|
|
██║████╗ ██║╚══██╔══╝██╔════╝██╔══██╗████╗ ████║██╔════╝██╔══██╗██║██╔══██╗██╔══██╗╚██╗ ██╔╝
|
|
██║██╔██╗ ██║ ██║ █████╗ ██████╔╝██╔████╔██║█████╗ ██║ ██║██║███████║██████╔╝ ╚████╔╝
|
|
██║██║╚██╗██║ ██║ ██╔══╝ ██╔══██╗██║╚██╔╝██║██╔══╝ ██║ ██║██║██╔══██║██╔══██╗ ╚██╔╝
|
|
██║██║ ╚████║ ██║ ███████╗██║ ██║██║ ╚═╝ ██║███████╗██████╔╝██║██║ ██║██║ ██║ ██║
|
|
╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝
|
|
Not used directly, but as part of other messages
|
|
*/
|
|
|
|
template<typename T>
|
|
static void LiveAPI_SetCommonMessageFields(T const msg, const eLiveAPI_EventTypes eventType)
|
|
{
|
|
if (msg->timestamp() == 0)
|
|
msg->set_timestamp(GetUnixTimeStamp());
|
|
if (msg->category().empty())
|
|
msg->set_category(LiveAPI_EventTypeToString(eventType));
|
|
}
|
|
|
|
static void LiveAPI_SetVector3D(rtech::liveapi::Vector3* const msgVec, const Vector3D* const dataVec)
|
|
{
|
|
msgVec->set_x(dataVec->x);
|
|
msgVec->set_y(dataVec->y);
|
|
msgVec->set_z(dataVec->z);
|
|
}
|
|
|
|
static void LiveAPI_SetDataCenter(rtech::liveapi::Datacenter* const msg, const char* const name)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(msg, eLiveAPI_EventTypes::datacenter);
|
|
msg->set_name(name);
|
|
}
|
|
|
|
static void LiveAPI_SetVersion(rtech::liveapi::Version* const msg)
|
|
{
|
|
msg->set_major_num(LIVEAPI_MAJOR_VERSION);
|
|
msg->set_minor_num(LIVEAPI_MINOR_VERSION);
|
|
msg->set_build_stamp(g_SDKDll.GetNTHeaders()->FileHeader.TimeDateStamp);
|
|
msg->set_revision(LIVEAPI_REVISION);
|
|
}
|
|
|
|
static bool LiveAPI_SetPlayerIdentityFields(HSQUIRRELVM const v, const SQTable* const table, rtech::liveapi::Player* const playerMsg)
|
|
{
|
|
bool ranLoop = false;
|
|
|
|
SQ_FOR_EACH_TABLE(table, i)
|
|
{
|
|
const SQTable::_HashNode& node = table->_nodes[i];
|
|
|
|
if (sq_isnull(node.key))
|
|
continue;
|
|
|
|
if (!ranLoop)
|
|
ranLoop = true;
|
|
|
|
if (!LiveAPI_CheckSwitchType(v, node.key))
|
|
return false;
|
|
|
|
const SQInteger fieldNum = _integer(node.key);
|
|
const SQObjectPtr& obj = node.val;
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::Player::kNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_name(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kTeamIdFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_teamid(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kPosFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_VECTOR, playerMsg, fieldNum);
|
|
LiveAPI_SetVector3D(playerMsg->mutable_pos(), _vector3d(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kAnglesFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_VECTOR, playerMsg, fieldNum);
|
|
LiveAPI_SetVector3D(playerMsg->mutable_angles(), _vector3d(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kCurrentHealthFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_currenthealth(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kMaxHealthFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_maxhealth(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kShieldHealthFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_shieldhealth(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kShieldMaxHealthFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_shieldmaxhealth(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kNucleusHashFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_nucleushash(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kHardwareNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_hardwarename(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kTeamNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_teamname(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kSquadIndexFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, playerMsg, fieldNum);
|
|
playerMsg->set_squadindex(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kCharacterFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_character(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::Player::kSkinFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, playerMsg, fieldNum);
|
|
playerMsg->set_skin(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, playerMsg);
|
|
}
|
|
}
|
|
|
|
if (!ranLoop)
|
|
LIVEAPI_EMPTY_TABLE_ERROR(v, playerMsg);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_SetInventoryItem(HSQUIRRELVM const v, const SQTable* const table, rtech::liveapi::InventoryItem* const event)
|
|
{
|
|
bool ranLoop = false;
|
|
|
|
SQ_FOR_EACH_TABLE(table, i)
|
|
{
|
|
const SQTable::_HashNode& node = table->_nodes[i];
|
|
|
|
if (sq_isnull(node.key))
|
|
continue;
|
|
|
|
if (!ranLoop)
|
|
ranLoop = true;
|
|
|
|
if (!LiveAPI_CheckSwitchType(v, node.key))
|
|
return false;
|
|
|
|
const SQInteger fieldNum = _integer(node.key);
|
|
const SQObjectPtr& obj = node.val;
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::InventoryItem::kQuantityFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_quantity(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::InventoryItem::kItemFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_item(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::InventoryItem::kExtraDataFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_extradata(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
}
|
|
|
|
if (!ranLoop)
|
|
LIVEAPI_EMPTY_TABLE_ERROR(v, event);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_SetLoadoutConfiguration(HSQUIRRELVM const v, rtech::liveapi::LoadoutConfiguration* const msg, const SQTable* const table)
|
|
{
|
|
bool ranOuterLoop = false;
|
|
bool ranInnerLoop = false;
|
|
|
|
SQ_FOR_EACH_TABLE(table, i)
|
|
{
|
|
const SQTable::_HashNode& node = table->_nodes[i];
|
|
|
|
if (sq_isnull(node.key))
|
|
continue;
|
|
|
|
if (!ranOuterLoop)
|
|
ranOuterLoop = true;
|
|
|
|
if (!LiveAPI_CheckSwitchType(v, node.key))
|
|
return false;
|
|
|
|
const SQInteger fieldNum = _integer(node.key);
|
|
const SQObjectPtr& obj = node.val;
|
|
|
|
rtech::liveapi::InventoryItem* (rtech::liveapi::LoadoutConfiguration:: * addFunctor)();
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::LoadoutConfiguration::kWeaponsFieldNumber:
|
|
{
|
|
addFunctor = &rtech::liveapi::LoadoutConfiguration::add_weapons;
|
|
break;
|
|
}
|
|
case rtech::liveapi::LoadoutConfiguration::kEquipmentFieldNumber:
|
|
{
|
|
addFunctor = &rtech::liveapi::LoadoutConfiguration::add_equipment;
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, msg);
|
|
}
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, msg, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
if (!ranInnerLoop)
|
|
ranInnerLoop = true;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_TABLE, msg, fieldNum);
|
|
|
|
if (!LiveAPI_SetInventoryItem(v, _table(fieldObj), (msg->*addFunctor)()))
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!ranOuterLoop || !ranInnerLoop)
|
|
LIVEAPI_EMPTY_TABLE_ERROR(v, msg);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
███████╗██╗ ██╗███████╗███╗ ██╗████████╗ ██╗ ██╗ █████╗ ███╗ ██╗██████╗ ██╗ ███████╗██████╗ ███████╗
|
|
██╔════╝██║ ██║██╔════╝████╗ ██║╚══██╔══╝ ██║ ██║██╔══██╗████╗ ██║██╔══██╗██║ ██╔════╝██╔══██╗██╔════╝
|
|
█████╗ ██║ ██║█████╗ ██╔██╗ ██║ ██║ ███████║███████║██╔██╗ ██║██║ ██║██║ █████╗ ██████╔╝███████╗
|
|
██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║╚██╗██║ ██║ ██╔══██║██╔══██║██║╚██╗██║██║ ██║██║ ██╔══╝ ██╔══██╗╚════██║
|
|
███████╗ ╚████╔╝ ███████╗██║ ╚████║ ██║ ██║ ██║██║ ██║██║ ╚████║██████╔╝███████╗███████╗██║ ██║███████║
|
|
╚══════╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝
|
|
NOTE: one handler may be used for multiple events to cut down on boilerplate code, this is possible if a message
|
|
has the same structure layout as another message; the actual field numbers don't matter, but the field names do!
|
|
*/
|
|
|
|
static bool LiveAPI_HandleInitEvent(rtech::liveapi::Init* const event, const eLiveAPI_EventTypes eventType)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
event->set_gameversion(Sys_GetBuildString());
|
|
LiveAPI_SetVersion(event->mutable_apiversion());
|
|
event->set_platform(Sys_GetPlatformString());
|
|
event->set_name(liveapi_session_name.GetString());
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleMatchSetup(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::MatchSetup* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::MatchSetup::kMapFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_map(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kPlaylistNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_playlistname(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kPlaylistDescFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_playlistdesc(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kDatacenterFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
LiveAPI_SetDataCenter(event->mutable_datacenter(), _string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kAimAssistOnFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_BOOL, event, fieldNum);
|
|
event->set_aimassiston(_bool(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kAnonymousModeFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_BOOL, event, fieldNum);
|
|
event->set_anonymousmode(_bool(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kServerIdFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_serverid(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchSetup::kStartingLoadoutFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
|
|
if (!LiveAPI_SetLoadoutConfiguration(v, event->mutable_startingloadout(), _table(obj)))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleAmmoUsed(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::AmmoUsed* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::AmmoUsed::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::AmmoUsed::kAmmoTypeFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_ammotype(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::AmmoUsed::kAmountUsedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_amountused(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::AmmoUsed::kOldAmmoCountFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_oldammocount(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::AmmoUsed::kNewAmmoCountFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_newammocount(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
static bool LiveAPI_HandleInventoryChange(HSQUIRRELVM const v, const SQObject& obj, T const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case event->kItemFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_item(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case event->kQuantityFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_quantity(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleInventoryDrop(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::InventoryDrop* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::InventoryDrop::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::InventoryDrop::kItemFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_item(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::InventoryDrop::kQuantityFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_quantity(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::InventoryDrop::kExtraDataFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, event, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_STRING, event, fieldNum);
|
|
event->add_extradata(_string(fieldObj)->_val);
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleGameStateChanged(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::GameStateChanged* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::GameStateChanged::kStateFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_state(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleMatchStateEnd(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::MatchStateEnd* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::MatchStateEnd::kStateFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_state(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::MatchStateEnd::kWinnersFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, event, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_TABLE, event, fieldNum);
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(fieldObj), event->add_winners()))
|
|
return false; // failure
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleObserverSwitched(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::ObserverSwitched* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::ObserverSwitched::kObserverFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_observer()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::ObserverSwitched::kTargetFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_target()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::ObserverSwitched::kTargetTeamFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, event, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_TABLE, event, fieldNum);
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(fieldObj), event->add_targetteam()))
|
|
return false; // failure
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleObserverAnnotation(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::ObserverAnnotation* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::ObserverAnnotation::kAnnotationSerialFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_annotationserial(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleBannerCollected(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::BannerCollected* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::BannerCollected::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::BannerCollected::kCollectedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_collected()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerRevive(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerRevive* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerRevive::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerRevive::kRevivedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_revived()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerDisconnected(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerDisconnected* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerDisconnected::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDisconnected::kCanReconnectFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_BOOL, event, fieldNum);
|
|
event->set_canreconnect(_bool(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDisconnected::kIsAliveFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_BOOL, event, fieldNum);
|
|
event->set_isalive(_bool(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
static bool LiveAPI_HandlePlayerAttackCommon(HSQUIRRELVM const v, const SQObject& obj, T const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kAttackerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_attacker()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case event->kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerDowned(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerDowned* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerDowned::kAttackerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_attacker()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDowned::kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDowned::kWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_weapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerKilled(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerKilled* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerKilled::kAttackerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_attacker()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerKilled::kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerKilled::kAwardedToFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_awardedto()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerKilled::kWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_weapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
static bool LiveAPI_HandleAbilityDamaged(HSQUIRRELVM const v, const SQObject& obj, T const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kAttackerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_attacker()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case event->kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case event->kDamageInflictedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_damageinflicted(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerDamaged(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerDamaged* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerDamaged::kAttackerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_attacker()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDamaged::kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDamaged::kWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_weapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerDamaged::kDamageInflictedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_damageinflicted(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerAssist(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerAssist* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerAssist::kAssistantFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_assistant()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerAssist::kVictimFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_victim()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerAssist::kWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_weapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// CharacterSelected
|
|
// PlayerConnected
|
|
// WraithPortal
|
|
// WarpGateUsed
|
|
template<typename T>
|
|
static bool LiveAPI_HandleSimplePlayerMessage(HSQUIRRELVM const v, const SQObject& obj, T const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleRingFinishedClosing(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::RingFinishedClosing* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kStageFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_stage(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case event->kCenterFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_VECTOR, event, fieldNum);
|
|
LiveAPI_SetVector3D(event->mutable_center(), _vector3d(obj));
|
|
|
|
break;
|
|
}
|
|
case event->kCurrentRadiusFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_currentradius(_float(obj));
|
|
|
|
break;
|
|
}
|
|
case event->kShrinkDurationFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_shrinkduration(_float(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleDeathFieldStartClosing(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::RingStartClosing* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::RingStartClosing::kStageFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_stage(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::RingStartClosing::kCenterFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_VECTOR, event, fieldNum);
|
|
LiveAPI_SetVector3D(event->mutable_center(), _vector3d(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::RingStartClosing::kCurrentRadiusFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_currentradius(_float(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::RingStartClosing::kEndRadiusFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_endradius(_float(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::RingStartClosing::kShrinkDurationFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_shrinkduration(_float(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleSquadEliminated(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::SquadEliminated* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::SquadEliminated::kPlayersFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, event, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_TABLE, event, fieldNum);
|
|
rtech::liveapi::Player* const player = event->add_players();
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(fieldObj), player))
|
|
return false; // failure
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
static bool LiveAPI_HandleLinkedEntityEvent(HSQUIRRELVM const v, const SQObject& obj, T const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case event->kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case event->kLinkedEntityFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_linkedentity(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleWeaponSwitchedEvent(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::WeaponSwitched* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::WeaponSwitched::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::WeaponSwitched::kOldWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_oldweapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::WeaponSwitched::kNewWeaponFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_newweapon(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleBlackMarketActionEvent(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::BlackMarketAction* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::BlackMarketAction::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::BlackMarketAction::kItemFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_item(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerUpgradeTierChanged(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerUpgradeTierChanged* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerUpgradeTierChanged::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerUpgradeTierChanged::kLevelFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_level(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleLegendUpgradeSelected(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::LegendUpgradeSelected* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::LegendUpgradeSelected::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::LegendUpgradeSelected::kUpgradeNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_upgradename(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::LegendUpgradeSelected::kUpgradeDescFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_upgradedesc(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::LegendUpgradeSelected::kLevelFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_level(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerRespawnTeam(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerRespawnTeam* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerRespawnTeam::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerRespawnTeam::kRespawnedFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_ARRAY, event, fieldNum);
|
|
const SQArray* const fieldArray = _array(obj);
|
|
|
|
for (SQInteger j = 0; j < fieldArray->Size(); j++)
|
|
{
|
|
const SQObject& fieldObj = fieldArray->_values[j];
|
|
|
|
if (sq_isnull(fieldObj))
|
|
continue;
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, fieldObj, OT_TABLE, event, fieldNum);
|
|
rtech::liveapi::Player* const player = event->add_respawned();
|
|
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(fieldObj), player))
|
|
return false; // failure
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandlePlayerStatChanged(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::PlayerStatChanged* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::PlayerStatChanged::kPlayerFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetPlayerIdentityFields(v, _table(obj), event->mutable_player()))
|
|
return false;
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerStatChanged::kStatNameFieldNumber:
|
|
{
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_statname(_string(obj)->_val);
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerStatChanged::kIntValueFieldNumber:
|
|
{
|
|
if (event->newValue_case() != rtech::liveapi::PlayerStatChanged::NEWVALUE_NOT_SET)
|
|
LIVEAPI_ONEOF_FIELD_ERROR(v, fieldNum, event);
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_INTEGER, event, fieldNum);
|
|
event->set_intvalue(_integer(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerStatChanged::kFloatValueFieldNumber:
|
|
{
|
|
if (event->newValue_case() != rtech::liveapi::PlayerStatChanged::NEWVALUE_NOT_SET)
|
|
LIVEAPI_ONEOF_FIELD_ERROR(v, fieldNum, event);
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_FLOAT, event, fieldNum);
|
|
event->set_floatvalue(_float(obj));
|
|
|
|
break;
|
|
}
|
|
case rtech::liveapi::PlayerStatChanged::kBoolValueFieldNumber:
|
|
{
|
|
if (event->newValue_case() != rtech::liveapi::PlayerStatChanged::NEWVALUE_NOT_SET)
|
|
LIVEAPI_ONEOF_FIELD_ERROR(v, fieldNum, event);
|
|
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_BOOL, event, fieldNum);
|
|
event->set_boolvalue(_bool(obj));
|
|
|
|
break;
|
|
}
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void LiveAPI_SetCustomVectorField(google::protobuf::Struct* const structData, const Vector3D* const vecData)
|
|
{
|
|
google::protobuf::Map<std::string, google::protobuf::Value>* const fieldData = structData->mutable_fields();
|
|
|
|
(*fieldData)["x"].set_number_value(vecData->x);
|
|
(*fieldData)["y"].set_number_value(vecData->y);
|
|
(*fieldData)["z"].set_number_value(vecData->z);
|
|
}
|
|
|
|
static bool LiveAPI_SetCustomTableFields(HSQUIRRELVM const v, google::protobuf::Struct* const structData, const SQTable* const tableData);
|
|
static bool LiveAPI_SetCustomArrayFields(HSQUIRRELVM const v, google::protobuf::ListValue* const listData, const SQArray* const arrayData);
|
|
|
|
static int s_currentDepth = 0;
|
|
|
|
static bool LiveAPI_SetCustomArrayFields(HSQUIRRELVM const v, google::protobuf::ListValue* const listData, const SQArray* const arrayData)
|
|
{
|
|
CDepthCounter<int> counter(s_currentDepth);
|
|
bool ranLoop = false;
|
|
|
|
for (SQInteger i = 0; i < arrayData->Size(); i++)
|
|
{
|
|
const SQObject& valueObj = arrayData->_values[i];
|
|
|
|
if (sq_isnull(valueObj))
|
|
continue;
|
|
|
|
if (!ranLoop)
|
|
ranLoop = true;
|
|
|
|
const SQObjectType valueType = sq_type(valueObj);
|
|
|
|
switch (valueType)
|
|
{
|
|
case OT_BOOL:
|
|
listData->add_values()->set_bool_value(_bool(valueObj));
|
|
break;
|
|
case OT_INTEGER:
|
|
listData->add_values()->set_number_value(_integer(valueObj));
|
|
break;
|
|
case OT_FLOAT:
|
|
listData->add_values()->set_number_value(_float(valueObj));
|
|
break;
|
|
case OT_STRING:
|
|
listData->add_values()->set_string_value(_string(valueObj)->_val);
|
|
break;
|
|
case OT_VECTOR:
|
|
LiveAPI_SetCustomVectorField(listData->add_values()->mutable_struct_value(), _vector3d(valueObj));
|
|
break;
|
|
case OT_ARRAY:
|
|
LIVEAPI_CHECK_RECURSION_DEPTH(v, counter.Get());
|
|
|
|
if (arrayData == _array(valueObj))
|
|
{
|
|
v_SQVM_RaiseError(v, "Attempted to nest array at depth \"%i\" into itself at index \"%i\".", counter.Get(), i);
|
|
return false;
|
|
}
|
|
|
|
if (!LiveAPI_SetCustomArrayFields(v, listData->add_values()->mutable_list_value(), _array(valueObj)))
|
|
return false;
|
|
|
|
break;
|
|
case OT_TABLE:
|
|
LIVEAPI_CHECK_RECURSION_DEPTH(v, counter.Get());
|
|
|
|
if (!LiveAPI_SetCustomTableFields(v, listData->add_values()->mutable_struct_value(), _table(valueObj)))
|
|
return false;
|
|
|
|
break;
|
|
default:
|
|
LIVEAPI_UNSUPPORTED_TYPE_ERROR(v, valueType, listData);
|
|
}
|
|
}
|
|
|
|
if (!ranLoop)
|
|
LIVEAPI_EMPTY_TABLE_ERROR(v, listData);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_SetCustomTableFields(HSQUIRRELVM const v, google::protobuf::Struct* const structData, const SQTable* const tableData)
|
|
{
|
|
CDepthCounter<int> counter(s_currentDepth);
|
|
bool ranLoop = false;
|
|
|
|
SQ_FOR_EACH_TABLE(tableData, i)
|
|
{
|
|
const SQTable::_HashNode& node = tableData->_nodes[i];
|
|
|
|
if (sq_isnull(node.key))
|
|
continue;
|
|
|
|
if (!ranLoop)
|
|
ranLoop = true;
|
|
|
|
const SQObjectType keyType = sq_type(node.key);
|
|
|
|
if (keyType != OT_STRING)
|
|
{
|
|
v_SQVM_RaiseError(v, "Key in table must be a \"%s\", got \"%s\" for message \"%s\" at depth \"%i\" at index \"%i\".",
|
|
IdType2Name(OT_STRING), IdType2Name(keyType), structData->GetTypeName().c_str(), counter.Get(), i);
|
|
|
|
return false;
|
|
}
|
|
|
|
const SQObjectType valueType = sq_type(node.val);
|
|
|
|
switch (valueType)
|
|
{
|
|
case OT_BOOL:
|
|
(*structData->mutable_fields())[_string(node.key)->_val].set_bool_value(_bool(node.val));
|
|
break;
|
|
case OT_INTEGER:
|
|
(*structData->mutable_fields())[_string(node.key)->_val].set_number_value(_integer(node.val));
|
|
break;
|
|
case OT_FLOAT:
|
|
(*structData->mutable_fields())[_string(node.key)->_val].set_number_value(_float(node.val));
|
|
break;
|
|
case OT_STRING:
|
|
(*structData->mutable_fields())[_string(node.key)->_val].set_string_value(_string(node.val)->_val);
|
|
break;
|
|
case OT_VECTOR:
|
|
LiveAPI_SetCustomVectorField((*structData->mutable_fields())[_string(node.key)->_val].mutable_struct_value(), _vector3d(node.val));
|
|
break;
|
|
case OT_ARRAY:
|
|
LIVEAPI_CHECK_RECURSION_DEPTH(v, counter.Get());
|
|
|
|
if (!LiveAPI_SetCustomArrayFields(v, (*structData->mutable_fields())[_string(node.key)->_val].mutable_list_value(), _array(node.val)))
|
|
return false;
|
|
|
|
break;
|
|
case OT_TABLE:
|
|
LIVEAPI_CHECK_RECURSION_DEPTH(v, counter.Get());
|
|
|
|
if (tableData == _table(node.val))
|
|
{
|
|
v_SQVM_RaiseError(v, "Attempted to nest table at depth \"%i\" into itself at index \"%i\".", counter.Get(), i);
|
|
return false;
|
|
}
|
|
|
|
if (!LiveAPI_SetCustomTableFields(v, (*structData->mutable_fields())[_string(node.key)->_val].mutable_struct_value(), _table(node.val)))
|
|
return false;
|
|
|
|
break;
|
|
default:
|
|
LIVEAPI_UNSUPPORTED_TYPE_ERROR(v, valueType, structData);
|
|
}
|
|
}
|
|
|
|
if (!ranLoop)
|
|
LIVEAPI_EMPTY_TABLE_ERROR(v, structData);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LiveAPI_HandleCustomEvent(HSQUIRRELVM const v, const SQObject& obj, rtech::liveapi::CustomEvent* const event,
|
|
const eLiveAPI_EventTypes eventType, const SQInteger fieldNum)
|
|
{
|
|
LiveAPI_SetCommonMessageFields(event, eventType);
|
|
|
|
switch (fieldNum)
|
|
{
|
|
case rtech::liveapi::CustomEvent::kNameFieldNumber:
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_STRING, event, fieldNum);
|
|
event->set_name(_string(obj)->_val);
|
|
|
|
break;
|
|
case rtech::liveapi::CustomEvent::kDataFieldNumber:
|
|
LIVEAPI_ENSURE_TYPE(v, obj, OT_TABLE, event, fieldNum);
|
|
if (!LiveAPI_SetCustomTableFields(v, event->mutable_data(), _table(obj)))
|
|
return false;
|
|
|
|
break;
|
|
default:
|
|
LIVEAPI_FIELD_ERROR(v, fieldNum, event);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
███████╗██╗ ██╗███████╗███╗ ██╗████████╗ ██████╗ ██╗███████╗██████╗ █████╗ ████████╗ ██████╗██╗ ██╗███████╗██████╗
|
|
██╔════╝██║ ██║██╔════╝████╗ ██║╚══██╔══╝ ██╔══██╗██║██╔════╝██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██║ ██║██╔════╝██╔══██╗
|
|
█████╗ ██║ ██║█████╗ ██╔██╗ ██║ ██║ ██║ ██║██║███████╗██████╔╝███████║ ██║ ██║ ███████║█████╗ ██████╔╝
|
|
██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██║╚════██║██╔═══╝ ██╔══██║ ██║ ██║ ██╔══██║██╔══╝ ██╔══██╗
|
|
███████╗ ╚████╔╝ ███████╗██║ ╚████║ ██║ ██████╔╝██║███████║██║ ██║ ██║ ██║ ╚██████╗██║ ██║███████╗██║ ██║
|
|
╚══════╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
|
|
*/
|
|
|
|
static void LiveAPI_SendEvent(const google::protobuf::Message* const msg)
|
|
{
|
|
s_liveAPIEvent.set_event_size(msg->ByteSize());
|
|
s_liveAPIEvent.mutable_gamemessage()->PackFrom(*msg);
|
|
|
|
LiveAPISystem()->LogEvent(&s_liveAPIEvent, &s_liveAPIEvent.gamemessage());
|
|
s_liveAPIEvent.Clear();
|
|
}
|
|
|
|
static bool LiveAPI_HandleEventByCategory(HSQUIRRELVM const v, const SQTable* const table, const eLiveAPI_EventTypes eventType)
|
|
{
|
|
google::protobuf::Message* msg = nullptr;
|
|
|
|
SQ_FOR_EACH_TABLE(table, i)
|
|
{
|
|
const SQTable::_HashNode& node = table->_nodes[i];
|
|
|
|
if (sq_isnull(node.key))
|
|
continue;
|
|
|
|
if (!LiveAPI_CheckSwitchType(v, node.key))
|
|
return false;
|
|
|
|
const SQInteger fieldNum = _integer(node.key);
|
|
const SQObjectPtr& obj = node.val;
|
|
|
|
bool ret = false;
|
|
|
|
switch (eventType)
|
|
{
|
|
case eLiveAPI_EventTypes::init:
|
|
msg = &s_init;
|
|
ret = LiveAPI_HandleInitEvent(&s_init, eventType);
|
|
break;
|
|
case eLiveAPI_EventTypes::matchSetup:
|
|
msg = &s_matchSetup;
|
|
ret = LiveAPI_HandleMatchSetup(v, obj, &s_matchSetup, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::ammoUsed:
|
|
msg = &s_ammoUsed;
|
|
ret = LiveAPI_HandleAmmoUsed(v, obj, &s_ammoUsed, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::arenasItemDeselected:
|
|
msg = &s_arenasItemDeselected;
|
|
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemDeselected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::arenasItemSelected:
|
|
msg = &s_arenasItemSelected;
|
|
ret = LiveAPI_HandleInventoryChange(v, obj, &s_arenasItemSelected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::bannerCollected:
|
|
msg = &s_bannerCollected;
|
|
ret = LiveAPI_HandleBannerCollected(v, obj, &s_bannerCollected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::customEvent:
|
|
msg = &s_customEvent;
|
|
ret = LiveAPI_HandleCustomEvent(v, obj, &s_customEvent, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::inventoryPickUp:
|
|
msg = &s_inventoryPickUp;
|
|
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryPickUp, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::inventoryDrop:
|
|
msg = &s_inventoryDrop;
|
|
ret = LiveAPI_HandleInventoryDrop(v, obj, &s_inventoryDrop, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::inventoryUse:
|
|
msg = &s_inventoryUse;
|
|
ret = LiveAPI_HandleInventoryChange(v, obj, &s_inventoryUse, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::gameStateChanged:
|
|
msg = &s_gameStateChanged;
|
|
ret = LiveAPI_HandleGameStateChanged(v, obj, &s_gameStateChanged, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::matchStateEnd:
|
|
msg = &s_matchStateEnd;
|
|
ret = LiveAPI_HandleMatchStateEnd(v, obj, &s_matchStateEnd, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::characterSelected:
|
|
msg = &s_characterSelected;
|
|
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_characterSelected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::warpGateUsed:
|
|
msg = &s_warpGateUsed;
|
|
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_warpGateUsed, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::wraithPortal:
|
|
msg = &s_wraithPortal;
|
|
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_wraithPortal, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerConnected:
|
|
msg = &s_playerConnected;
|
|
ret = LiveAPI_HandleSimplePlayerMessage(v, obj, &s_playerConnected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerRevive:
|
|
msg = &s_playerRevive;
|
|
ret = LiveAPI_HandlePlayerRevive(v, obj, &s_playerRevive, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerDisconnected:
|
|
msg = &s_playerDisconnected;
|
|
ret = LiveAPI_HandlePlayerDisconnected(v, obj, &s_playerDisconnected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerDamaged:
|
|
msg = &s_playerDamaged;
|
|
ret = LiveAPI_HandlePlayerDamaged(v, obj, &s_playerDamaged, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerDowned:
|
|
msg = &s_playerDowned;
|
|
ret = LiveAPI_HandlePlayerDowned(v, obj, &s_playerDowned, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerKilled:
|
|
msg = &s_playerKilled;
|
|
ret = LiveAPI_HandlePlayerKilled(v, obj, &s_playerKilled, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerAssist:
|
|
msg = &s_playerAssist;
|
|
ret = LiveAPI_HandlePlayerAssist(v, obj, &s_playerAssist, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerRespawnTeam:
|
|
msg = &s_playerRespawnTeam;
|
|
ret = LiveAPI_HandlePlayerRespawnTeam(v, obj, &s_playerRespawnTeam, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerStatChanged:
|
|
msg = &s_playerStatChanged;
|
|
ret = LiveAPI_HandlePlayerStatChanged(v, obj, &s_playerStatChanged, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerUpgradeTierChanged:
|
|
msg = &s_playerUpgradeTierChanged;
|
|
ret = LiveAPI_HandlePlayerUpgradeTierChanged(v, obj, &s_playerUpgradeTierChanged, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::legendUpgradeSelected:
|
|
msg = &s_legendUpgradeSelected;
|
|
ret = LiveAPI_HandleLegendUpgradeSelected(v, obj, &s_legendUpgradeSelected, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::gibraltarShieldAbsorbed:
|
|
msg = &s_gibraltarShieldAbsorbed;
|
|
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_gibraltarShieldAbsorbed, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::revenantForgedShadowDamaged:
|
|
msg = &s_revenantForgedShadowDamaged;
|
|
ret = LiveAPI_HandleAbilityDamaged(v, obj, &s_revenantForgedShadowDamaged, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::ringStartClosing:
|
|
msg = &s_ringStartClosing;
|
|
ret = LiveAPI_HandleDeathFieldStartClosing(v, obj, &s_ringStartClosing, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::ringFinishedClosing:
|
|
msg = &s_ringFinishedClosing;
|
|
ret = LiveAPI_HandleRingFinishedClosing(v, obj, &s_ringFinishedClosing, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::squadEliminated:
|
|
msg = &s_squadEliminated;
|
|
ret = LiveAPI_HandleSquadEliminated(v, obj, &s_squadEliminated, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::ziplineUsed:
|
|
msg = &s_ziplineUsed;
|
|
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_ziplineUsed, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::grenadeThrown:
|
|
msg = &s_grenadeThrown;
|
|
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_grenadeThrown, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::playerAbilityUsed:
|
|
msg = &s_playerAbilityUsed;
|
|
ret = LiveAPI_HandleLinkedEntityEvent(v, obj, &s_playerAbilityUsed, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::weaponSwitched:
|
|
msg = &s_weaponSwitched;
|
|
ret = LiveAPI_HandleWeaponSwitchedEvent(v, obj, &s_weaponSwitched, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::blackMarketAction:
|
|
msg = &s_blackMarketAction;
|
|
ret = LiveAPI_HandleBlackMarketActionEvent(v, obj, &s_blackMarketAction, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::observerSwitched:
|
|
msg = &s_observerSwitched;
|
|
ret = LiveAPI_HandleObserverSwitched(v, obj, &s_observerSwitched, eventType, fieldNum);
|
|
break;
|
|
case eLiveAPI_EventTypes::observerAnnotation:
|
|
msg = &s_observerAnnotation;
|
|
ret = LiveAPI_HandleObserverAnnotation(v, obj, &s_observerAnnotation, eventType, fieldNum);
|
|
break;
|
|
default:
|
|
v_SQVM_RaiseError(v, "Event type \"%d\" not found.", eventType);
|
|
return false;
|
|
}
|
|
|
|
if (!ret)
|
|
{
|
|
Assert(msg);
|
|
|
|
msg->Clear();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!msg) // Script bug, e.g. giving an empty table (either completely empty or filled with null)
|
|
{
|
|
v_SQVM_RaiseError(v, "Empty table on event type \"%d\".", eventType);
|
|
return false;
|
|
}
|
|
|
|
LiveAPI_SendEvent(msg);
|
|
msg->Clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
█████╗ ██████╗ ███████╗████████╗██████╗ █████╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗███████╗
|
|
██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║██╔════╝
|
|
███████║██████╔╝███████╗ ██║ ██████╔╝███████║██║ ██║ ██║██║ ██║██╔██╗ ██║███████╗
|
|
██╔══██║██╔══██╗╚════██║ ██║ ██╔══██╗██╔══██║██║ ██║ ██║██║ ██║██║╚██╗██║╚════██║
|
|
██║ ██║██████╔╝███████║ ██║ ██║ ██║██║ ██║╚██████╗ ██║ ██║╚██████╔╝██║ ╚████║███████║
|
|
╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
|
|
Code exposed to scripts
|
|
*/
|
|
|
|
namespace VScriptCode
|
|
{
|
|
namespace Server
|
|
{
|
|
SQRESULT LiveAPI_IsValidToRun(HSQUIRRELVM v);
|
|
SQRESULT LiveAPI_LogRaw(HSQUIRRELVM v);
|
|
|
|
SQRESULT LiveAPI_StartLogging(HSQUIRRELVM v);
|
|
SQRESULT LiveAPI_StopLogging(HSQUIRRELVM v);
|
|
}
|
|
}
|
|
|
|
SQRESULT VScriptCode::Server::LiveAPI_IsValidToRun(HSQUIRRELVM v)
|
|
{
|
|
sq_pushbool(v, LiveAPISystem()->IsValidToRun());
|
|
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
|
}
|
|
|
|
SQRESULT VScriptCode::Server::LiveAPI_LogRaw(HSQUIRRELVM v)
|
|
{
|
|
if (!LiveAPISystem()->IsEnabled())
|
|
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
|
|
|
SQRESULT result = SQ_OK;
|
|
const SQObjectPtr& object = v->GetUp(-2);
|
|
|
|
if (sq_istable(object))
|
|
{
|
|
const SQTable* const table = _table(object);
|
|
SQInteger eventType = 0;
|
|
|
|
if (SQ_FAILED(sq_getinteger(v, 3, &eventType)))
|
|
{
|
|
v_SQVM_ScriptError("Second argument must be an integer.");
|
|
result = SQ_FAIL;
|
|
}
|
|
else if (!LiveAPI_HandleEventByCategory(v, table, eLiveAPI_EventTypes(eventType)))
|
|
result = SQ_ERROR;
|
|
}
|
|
else
|
|
{
|
|
v_SQVM_ScriptError("First argument must be a table.");
|
|
result = SQ_FAIL;
|
|
}
|
|
|
|
SCRIPT_CHECK_AND_RETURN(v, result);
|
|
}
|
|
|
|
SQRESULT VScriptCode::Server::LiveAPI_StartLogging(HSQUIRRELVM v)
|
|
{
|
|
LiveAPISystem()->CreateLogger();
|
|
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
|
}
|
|
|
|
SQRESULT VScriptCode::Server::LiveAPI_StopLogging(HSQUIRRELVM v)
|
|
{
|
|
LiveAPISystem()->DestroyLogger();
|
|
SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
|
|
}
|
|
|
|
void Script_RegisterLiveAPIFunctions(CSquirrelVM* const s)
|
|
{
|
|
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, LiveAPI_IsValidToRun, "Whether the LiveAPI system is enabled and able to run", "bool", "");
|
|
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, LiveAPI_LogRaw, "VM bridge to the LiveAPI logger from scripts", "void", "table< int, var > data, int eventType");
|
|
|
|
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, LiveAPI_StartLogging, "Start the LiveAPI session logger", "void", "");
|
|
DEFINE_SERVER_SCRIPTFUNC_NAMED(s, LiveAPI_StopLogging, "Stop the LiveAPI session logger", "void", "");
|
|
}
|
|
|
|
void Script_RegisterLiveAPIEnums(CSquirrelVM* const s)
|
|
{
|
|
DEFINE_SCRIPTENUM_NAMED(s, "eLiveAPI_EventTypes", 0,
|
|
"ammoUsed",
|
|
"arenasItemDeselected",
|
|
"arenasItemSelected",
|
|
"bannerCollected",
|
|
"blackMarketAction",
|
|
//"changeCamera",
|
|
"characterSelected",
|
|
//"checkedState",
|
|
//"clientState",
|
|
//"customMatch_CreateLobby",
|
|
//"customMatch_GetLobbyPlayers",
|
|
//"customMatch_GetSettings",
|
|
//"customMatch_JoinLobby",
|
|
//"customMatch_KickPlayer",
|
|
//"customMatch_LeaveLobby",
|
|
//"customMatch_LobbyPlayer",
|
|
//"customMatch_LobbyPlayers",
|
|
//"customMatch_SendChat",
|
|
//"customMatch_SetMatchmaking",
|
|
//"customMatch_SetReady",
|
|
//"customMatch_SetSettings",
|
|
//"customMatch_SetTeam",
|
|
//"customMatch_SetTeamName",
|
|
"customEvent",
|
|
"datacenter",
|
|
//"gameConVar",
|
|
"gameStateChanged",
|
|
"gibraltarShieldAbsorbed",
|
|
//"globalVars",
|
|
"grenadeThrown",
|
|
"init",
|
|
"inventoryDrop",
|
|
"inventoryItem",
|
|
"inventoryPickUp",
|
|
"inventoryUse",
|
|
"legendUpgradeSelected",
|
|
"liveAPIEvent",
|
|
"loadoutConfiguration",
|
|
"matchSetup",
|
|
"matchStateEnd",
|
|
"observerAnnotation",
|
|
"observerSwitched",
|
|
//"pauseToggle",
|
|
"player",
|
|
"playerAbilityUsed",
|
|
"playerAssist",
|
|
"playerConnected",
|
|
"playerDamaged",
|
|
"playerDisconnected",
|
|
"playerDowned",
|
|
"playerKilled",
|
|
"playerRespawnTeam",
|
|
"playerRevive",
|
|
"playerStatChanged",
|
|
"playerUpgradeTierChanged",
|
|
//"request",
|
|
//"requestStatus",
|
|
//"response",
|
|
"revenantForgedShadowDamaged",
|
|
"ringFinishedClosing",
|
|
"ringStartClosing",
|
|
//"runCommand",
|
|
//"scriptCall",
|
|
"squadEliminated",
|
|
//"stateCheck",
|
|
//"svcMsgOverflow",
|
|
//"svcMsgRemoteScript",
|
|
"vector3",
|
|
"version",
|
|
"warpGateUsed",
|
|
"weaponSwitched",
|
|
"wraithPortal",
|
|
"ziplineUsed"
|
|
);
|
|
}
|