feat(lua): Allow lua scripts to flag modders with a custom reason if needed. (#2248)
This commit is contained in:
parent
f9c948f909
commit
94838af288
@ -18,6 +18,7 @@ class DocKind(Enum):
|
||||
Constructor = "constructor"
|
||||
Function = "function"
|
||||
Tabs = "tabs"
|
||||
Infraction = "infraction"
|
||||
|
||||
|
||||
class Table:
|
||||
@ -324,7 +325,10 @@ def parse_lua_api_doc(folder_path):
|
||||
.lower()
|
||||
)
|
||||
|
||||
if doc_kind is not DocKind.Tabs:
|
||||
if (
|
||||
doc_kind is not DocKind.Tabs
|
||||
and doc_kind is not DocKind.Infraction
|
||||
):
|
||||
continue
|
||||
|
||||
if doc_kind is not None and "//" in line:
|
||||
@ -367,7 +371,10 @@ def parse_lua_api_doc(folder_path):
|
||||
line,
|
||||
line_lower,
|
||||
)
|
||||
case DocKind.Tabs: parse_tabs_doc(file)
|
||||
case DocKind.Tabs:
|
||||
parse_tabs_doc(file)
|
||||
case DocKind.Infraction:
|
||||
parse_infraction_doc(file)
|
||||
case _:
|
||||
# print("unsupported doc kind: " + str(doc_kind))
|
||||
pass
|
||||
@ -386,6 +393,7 @@ def parse_table_doc(cur_table, line, line_lower):
|
||||
|
||||
return cur_table
|
||||
|
||||
|
||||
def parse_class_doc(cur_class, line, line_lower):
|
||||
if is_lua_doc_comment_startswith(line_lower, "name"):
|
||||
class_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
@ -402,28 +410,43 @@ def parse_class_doc(cur_class, line, line_lower):
|
||||
|
||||
|
||||
def parse_function_doc(cur_function, cur_table, cur_class, line, line_lower):
|
||||
if is_lua_doc_comment_startswith(line_lower, "table") and lua_api_comment_separator in line_lower:
|
||||
if (
|
||||
is_lua_doc_comment_startswith(line_lower, "table")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
table_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_table = make_table(table_name)
|
||||
|
||||
cur_function = Function("Didnt get name yet", cur_table, [], None, "", "")
|
||||
cur_table.functions.append(cur_function)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "class") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "class")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
class_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_class = make_class(class_name)
|
||||
|
||||
cur_function = Function("Didnt get name yet", cur_class, [], None, "", "")
|
||||
cur_class.functions.append(cur_function)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "name") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "name")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
function_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_function.name = function_name
|
||||
|
||||
if function_name not in functions:
|
||||
functions[function_name] = cur_function
|
||||
elif is_lua_doc_comment_startswith(line_lower, "param") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "param")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
parameter = make_parameter_from_doc_line(line)
|
||||
cur_function.parameters.append(parameter)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "return") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "return")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
return_info = line.split(lua_api_comment_separator, 2)
|
||||
try:
|
||||
cur_function.return_type = return_info[1].strip()
|
||||
@ -439,19 +462,28 @@ def parse_function_doc(cur_function, cur_table, cur_class, line, line_lower):
|
||||
|
||||
|
||||
def parse_field_doc(cur_field, cur_table, cur_class, line, line_lower):
|
||||
if is_lua_doc_comment_startswith(line_lower, "table") and lua_api_comment_separator in line_lower:
|
||||
if (
|
||||
is_lua_doc_comment_startswith(line_lower, "table")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
table_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_table = make_table(table_name)
|
||||
|
||||
cur_field = Field("Didnt get name yet", "", "")
|
||||
cur_table.fields.append(cur_field)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "class") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "class")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
class_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_class = make_class(class_name)
|
||||
|
||||
cur_field = Field("Didnt get name yet", "", "")
|
||||
cur_class.fields.append(cur_field)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "field") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "field")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
field_info = line.split(lua_api_comment_separator, 2)
|
||||
cur_field.name = field_info[1].strip()
|
||||
cur_field.type_ = field_info[2].strip()
|
||||
@ -467,13 +499,19 @@ def parse_field_doc(cur_field, cur_table, cur_class, line, line_lower):
|
||||
|
||||
|
||||
def parse_constructor_doc(cur_constructor, cur_class, line, line_lower):
|
||||
if is_lua_doc_comment_startswith(line_lower, "class") and lua_api_comment_separator in line_lower:
|
||||
if (
|
||||
is_lua_doc_comment_startswith(line_lower, "class")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
class_name = line.split(lua_api_comment_separator, 1)[1].strip()
|
||||
cur_class = make_class(class_name)
|
||||
|
||||
cur_constructor = Constructor(cur_class, [], "")
|
||||
cur_class.constructors.append(cur_constructor)
|
||||
elif is_lua_doc_comment_startswith(line_lower, "param") and lua_api_comment_separator in line_lower:
|
||||
elif (
|
||||
is_lua_doc_comment_startswith(line_lower, "param")
|
||||
and lua_api_comment_separator in line_lower
|
||||
):
|
||||
parameter = make_parameter_from_doc_line(line)
|
||||
cur_constructor.parameters.append(parameter)
|
||||
else:
|
||||
@ -485,6 +523,8 @@ def parse_constructor_doc(cur_constructor, cur_class, line, line_lower):
|
||||
|
||||
|
||||
tabs_enum = []
|
||||
|
||||
|
||||
def parse_tabs_doc(file):
|
||||
start_parsing = False
|
||||
for line in file:
|
||||
@ -503,7 +543,29 @@ def parse_tabs_doc(file):
|
||||
continue
|
||||
else:
|
||||
tabs_enum.append(line.replace(",", "").strip())
|
||||
|
||||
|
||||
|
||||
infraction_enum = []
|
||||
|
||||
|
||||
def parse_infraction_doc(file):
|
||||
start_parsing = False
|
||||
for line in file:
|
||||
if "enum class" in line.lower():
|
||||
start_parsing = True
|
||||
continue
|
||||
|
||||
if start_parsing:
|
||||
if "};" in line.lower():
|
||||
return
|
||||
if "{" == line.lower().strip():
|
||||
continue
|
||||
if "//" in line.lower():
|
||||
continue
|
||||
if "" == line.lower().strip():
|
||||
continue
|
||||
else:
|
||||
infraction_enum.append(line.replace(",", "").strip())
|
||||
|
||||
|
||||
def make_parameter_from_doc_line(line):
|
||||
@ -519,13 +581,15 @@ def make_parameter_from_doc_line(line):
|
||||
|
||||
return Parameter(param_name, param_type, param_desc)
|
||||
|
||||
|
||||
def sanitize_description(line):
|
||||
if line.startswith("// ") and line[3] != ' ':
|
||||
if line.startswith("// ") and line[3] != " ":
|
||||
line = line[3:]
|
||||
if line.startswith("//"):
|
||||
line = line[2:]
|
||||
return line.rstrip()
|
||||
|
||||
|
||||
def is_lua_doc_comment_startswith(line_lower, starts_with_text):
|
||||
return line_lower.replace("//", "").strip().startswith(starts_with_text)
|
||||
|
||||
@ -550,7 +614,8 @@ if os.path.exists(tabs_file_name):
|
||||
os.remove(tabs_file_name)
|
||||
f = open(tabs_file_name, "a")
|
||||
|
||||
f.write("""# Tabs
|
||||
f.write(
|
||||
"""# Tabs
|
||||
|
||||
All the tabs from the menu are listed below, used as parameter for adding gui elements to them.
|
||||
|
||||
@ -565,16 +630,42 @@ end)
|
||||
|
||||
For a complete list of available gui functions, please refer to the tab class documentation and the gui table documentation.
|
||||
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(f"## Tab Count: {len(tabs_enum)}\n\n")
|
||||
|
||||
# Minus the first, because it's the `NONE` tab, minus the last one because it's for runtime defined tabs.
|
||||
for i in range(1, len(tabs_enum) - 1 ):
|
||||
for i in range(1, len(tabs_enum) - 1):
|
||||
f.write("### `GUI_TAB_" + tabs_enum[i] + "`\n")
|
||||
|
||||
f.close()
|
||||
|
||||
infraction_file_name = f"../lua/infraction.md"
|
||||
if os.path.exists(infraction_file_name):
|
||||
os.remove(infraction_file_name)
|
||||
f = open(infraction_file_name, "a")
|
||||
|
||||
f.write(
|
||||
"""# Infraction
|
||||
|
||||
All the infraction from the menu are listed below, used as parameter for adding an infraction to a given player, for flagging them as modder.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
network.flag_player_as_modder(player_index, infraction.CUSTOM_REASON, "My custom reason on why the player is flagged as a modder")
|
||||
```
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(f"## Infraction Count: {len(infraction_enum)}\n\n")
|
||||
|
||||
for i in range(0, len(infraction_enum)):
|
||||
f.write("### `" + infraction_enum[i] + "`\n")
|
||||
|
||||
f.close()
|
||||
|
||||
try:
|
||||
os.makedirs("./classes/")
|
||||
except:
|
||||
@ -589,13 +680,13 @@ for class_name, class_ in classes.items():
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
commands_file_name = f"./commands.md"
|
||||
if os.path.exists(commands_file_name):
|
||||
os.remove(commands_file_name)
|
||||
f = open(commands_file_name, "a")
|
||||
|
||||
f.write("""# Commands
|
||||
f.write(
|
||||
"""# Commands
|
||||
|
||||
All the current commands from the menu are listed below.
|
||||
|
||||
@ -608,7 +699,8 @@ command.call_player(somePlayerIndex, "spawn", {joaat("adder")})
|
||||
|
||||
For a complete list of available command functions, please refer to the command table documentation.
|
||||
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
commands = []
|
||||
@ -629,4 +721,4 @@ for cmd in commands:
|
||||
f.write(f"Arg Count: {arg_count}\n")
|
||||
f.write("\n")
|
||||
|
||||
f.close()
|
||||
f.close()
|
||||
|
23
docs/lua/infraction.md
Normal file
23
docs/lua/infraction.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Infraction
|
||||
|
||||
All the infraction from the menu are listed below, used as parameter for adding an infraction to a given player, for flagging them as modder.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
network.flag_player_as_modder(player_index, infraction.CUSTOM_REASON, "My custom reason on why the player is flagged as a modder")
|
||||
```
|
||||
|
||||
## Infraction Count: 12
|
||||
|
||||
### `TRIGGERED_ANTICHEAT`
|
||||
### `TRIED_CRASH_PLAYER`
|
||||
### `TRIED_KICK_PLAYER`
|
||||
### `ATTACKING_WITH_GODMODE`
|
||||
### `ATTACKING_WITH_INVISIBILITY`
|
||||
### `ATTACKING_WHEN_HIDDEN_FROM_PLAYER_LIST`
|
||||
### `SPOOFED_DATA`
|
||||
### `SPOOFED_HOST_TOKEN`
|
||||
### `INVALID_PLAYER_MODEL`
|
||||
### `SUPER_JUMP`
|
||||
### `UNDEAD_OTR`
|
||||
### `CUSTOM_REASON`
|
@ -2,7 +2,7 @@
|
||||
|
||||
Table containing helper functions for network related features.
|
||||
|
||||
## Functions (10)
|
||||
## Functions (11)
|
||||
|
||||
### `trigger_script_event(bitset, _args)`
|
||||
|
||||
@ -79,16 +79,18 @@ integer = network.get_selected_player()
|
||||
integer = network.get_selected_database_player_rockstar_id()
|
||||
```
|
||||
|
||||
### `flag_player_as_modder(player_idx)`
|
||||
### `flag_player_as_modder(player_idx, reason, custom_reason)`
|
||||
|
||||
Flags the given player as a modder in our local database.
|
||||
|
||||
- **Parameters:**
|
||||
- `player_idx` (integer): Index of the player.
|
||||
- `reason` (Infraction): Reason why the player is flagged as a modder, if the infraction is CUSTOM_REASON, then the custom_reason string is added in the local database. For a full list of the possible infraction reasons to use, please check the infraction page.
|
||||
- `custom_reason` (string): Optional, required only when the infraction is CUSTOM_REASON. The custom reason why the player is flagged as a modder.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
network.flag_player_as_modder(player_idx)
|
||||
network.flag_player_as_modder(player_idx, reason, custom_reason)
|
||||
```
|
||||
|
||||
### `is_player_flagged_as_modder(player_idx)`
|
||||
@ -104,6 +106,19 @@ network.flag_player_as_modder(player_idx)
|
||||
boolean = network.is_player_flagged_as_modder(player_idx)
|
||||
```
|
||||
|
||||
### `get_flagged_modder_reason(player_idx)`
|
||||
|
||||
- **Parameters:**
|
||||
- `player_idx` (integer): Index of the player.
|
||||
|
||||
- **Returns:**
|
||||
- `string`: Returns a string which contains the reason(s) why the player is flagged as a modder.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
string = network.get_flagged_modder_reason(player_idx)
|
||||
```
|
||||
|
||||
### `force_script_host(script_name)`
|
||||
|
||||
Try to force ourself to be host for the given GTA Script.
|
||||
|
@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
#include "gta/joaat.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
// Add new values to the bottom
|
||||
// Lua API: Infraction
|
||||
enum class Infraction
|
||||
{
|
||||
// Add new values to the bottom (for serialization)
|
||||
|
||||
DESYNC_PROTECTION, // do not use
|
||||
BREAKUP_KICK_DETECTED, // do not use
|
||||
LOST_CONNECTION_KICK_DETECTED, // do not use
|
||||
@ -22,24 +23,7 @@ namespace big
|
||||
INVALID_PLAYER_MODEL,
|
||||
SUPER_JUMP,
|
||||
UNDEAD_OTR,
|
||||
};
|
||||
|
||||
inline std::unordered_map<Infraction, const char*> infraction_desc = {
|
||||
{Infraction::DESYNC_PROTECTION, "Used desync protections"},
|
||||
{Infraction::BREAKUP_KICK_DETECTED, "Kicked someone using breakup kick"},
|
||||
{Infraction::LOST_CONNECTION_KICK_DETECTED, "Tried to kick someone using lost connection kick"},
|
||||
{Infraction::SPOOFED_ROCKSTAR_ID, "Had spoofed RID"},
|
||||
{Infraction::TRIGGERED_ANTICHEAT, "Triggered Rockstar's anticheat"},
|
||||
{Infraction::TRIED_CRASH_PLAYER, "Tried to crash you"},
|
||||
{Infraction::TRIED_KICK_PLAYER, "Tried to kick you"},
|
||||
{Infraction::BLAME_EXPLOSION_DETECTED, "Tried to blame someone for their explosion"},
|
||||
{Infraction::ATTACKING_WITH_GODMODE, "Attacked someone while using godmode"},
|
||||
{Infraction::ATTACKING_WITH_INVISIBILITY, "Attacked someone while being invisible"},
|
||||
{Infraction::ATTACKING_WHEN_HIDDEN_FROM_PLAYER_LIST, "Attacked someone while being hidden from the player list"},
|
||||
{Infraction::SPOOFED_DATA, "Had spoofed data"},
|
||||
{Infraction::SPOOFED_HOST_TOKEN, "Had spoofed their host token"},
|
||||
{Infraction::INVALID_PLAYER_MODEL, "Had used an invalid player model"},
|
||||
{Infraction::SUPER_JUMP, "Had used super jump"},
|
||||
{Infraction::UNDEAD_OTR, "Had used undead OTR"},
|
||||
// So that lua scripts can add a custom runtime reason.
|
||||
CUSTOM_REASON,
|
||||
};
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#include "services/player_database/player_database_service.hpp"
|
||||
#include "util/notify.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
#include "util/session.hpp"
|
||||
#include "util/system.hpp"
|
||||
#include "util/teleport.hpp"
|
||||
|
||||
@ -100,19 +101,26 @@ namespace lua::network
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void flag_player_as_modder(int player_idx, big::Infraction reason)
|
||||
{
|
||||
if (auto player = big::g_player_service->get_by_id(player_idx))
|
||||
{
|
||||
big::session::add_infraction(player, reason);
|
||||
}
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: network
|
||||
// Name: flag_player_as_modder
|
||||
// Param: player_idx: integer: Index of the player.
|
||||
// Param: reason: Infraction: Reason why the player is flagged as a modder, if the infraction is CUSTOM_REASON, then the custom_reason string is added in the local database. For a full list of the possible infraction reasons to use, please check the infraction page.
|
||||
// Param: custom_reason: string: Optional, required only when the infraction is CUSTOM_REASON. The custom reason why the player is flagged as a modder.
|
||||
// Flags the given player as a modder in our local database.
|
||||
static void flag_player_as_modder(int player_idx)
|
||||
static void flag_player_as_modder_custom_reason(int player_idx, big::Infraction reason, const std::string& custom_reason)
|
||||
{
|
||||
if (auto player = big::g_player_service->get_by_id(player_idx))
|
||||
{
|
||||
auto pers = big::g_player_database_service->get_or_create_player(player);
|
||||
pers->is_modder = true;
|
||||
big::g_player_database_service->save();
|
||||
player->is_modder = true;
|
||||
big::session::add_infraction(player, reason, custom_reason);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +137,21 @@ namespace lua::network
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: network
|
||||
// Name: get_flagged_modder_reason
|
||||
// Param: player_idx: integer: Index of the player.
|
||||
// Returns: string: Returns a string which contains the reason(s) why the player is flagged as a modder.
|
||||
static std::string get_flagged_modder_reason(int player_idx)
|
||||
{
|
||||
if (auto player = big::g_player_service->get_by_id(player_idx))
|
||||
{
|
||||
return big::g_player_database_service->get_or_create_player(player)->get_all_infraction_descriptions();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// Lua API: Function
|
||||
// Table: network
|
||||
// Name: force_script_host
|
||||
@ -158,16 +181,39 @@ namespace lua::network
|
||||
|
||||
void bind(sol::state& state)
|
||||
{
|
||||
auto ns = state["network"].get_or_create<sol::table>();
|
||||
state.new_enum<big::Infraction>("infraction",
|
||||
{
|
||||
{"ATTACKING_WHEN_HIDDEN_FROM_PLAYER_LIST", big::Infraction::ATTACKING_WHEN_HIDDEN_FROM_PLAYER_LIST},
|
||||
{"ATTACKING_WITH_GODMODE", big::Infraction::ATTACKING_WITH_GODMODE},
|
||||
{"ATTACKING_WITH_INVISIBILITY", big::Infraction::ATTACKING_WITH_INVISIBILITY},
|
||||
{"BLAME_EXPLOSION_DETECTED", big::Infraction::BLAME_EXPLOSION_DETECTED},
|
||||
{"BREAKUP_KICK_DETECTED", big::Infraction::BREAKUP_KICK_DETECTED},
|
||||
{"CUSTOM_REASON", big::Infraction::CUSTOM_REASON},
|
||||
{"DESYNC_PROTECTION", big::Infraction::DESYNC_PROTECTION},
|
||||
{"INVALID_PLAYER_MODEL", big::Infraction::INVALID_PLAYER_MODEL},
|
||||
{"LOST_CONNECTION_KICK_DETECTED", big::Infraction::LOST_CONNECTION_KICK_DETECTED},
|
||||
{"SPOOFED_DATA", big::Infraction::SPOOFED_DATA},
|
||||
{"SPOOFED_HOST_TOKEN", big::Infraction::SPOOFED_HOST_TOKEN},
|
||||
{"SPOOFED_ROCKSTAR_ID", big::Infraction::SPOOFED_ROCKSTAR_ID},
|
||||
{"SUPER_JUMP", big::Infraction::SUPER_JUMP},
|
||||
{"TRIED_CRASH_PLAYER", big::Infraction::TRIED_CRASH_PLAYER},
|
||||
{"TRIED_KICK_PLAYER", big::Infraction::TRIED_KICK_PLAYER},
|
||||
{"TRIGGERED_ANTICHEAT", big::Infraction::TRIGGERED_ANTICHEAT},
|
||||
{"UNDEAD_OTR", big::Infraction::UNDEAD_OTR},
|
||||
});
|
||||
|
||||
auto ns = state["network"].get_or_create<sol::table>();
|
||||
|
||||
ns["trigger_script_event"] = trigger_script_event;
|
||||
ns["give_pickup_rewards"] = give_pickup_rewards;
|
||||
ns["set_player_coords"] = set_player_coords;
|
||||
ns["set_all_player_coords"] = set_all_player_coords;
|
||||
ns["get_selected_player"] = get_selected_player;
|
||||
ns["get_selected_database_player_rockstar_id"] = get_selected_database_player_rockstar_id;
|
||||
ns["flag_player_as_modder"] = flag_player_as_modder;
|
||||
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
|
||||
ns["force_script_host"] = force_script_host;
|
||||
ns["send_chat_message"] = send_chat_message;
|
||||
ns["flag_player_as_modder"] = sol::overload(flag_player_as_modder, flag_player_as_modder_custom_reason);
|
||||
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
|
||||
ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
|
||||
ns["force_script_host"] = force_script_host;
|
||||
ns["send_chat_message"] = send_chat_message;
|
||||
}
|
||||
}
|
63
src/services/player_database/persistent_player.cpp
Normal file
63
src/services/player_database/persistent_player.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "persistent_player.hpp"
|
||||
|
||||
#include "core/data/infractions.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
static std::unordered_map<Infraction, const char*> infraction_desc = {
|
||||
{Infraction::DESYNC_PROTECTION, "Used desync protections"},
|
||||
{Infraction::BREAKUP_KICK_DETECTED, "Kicked someone using breakup kick"},
|
||||
{Infraction::LOST_CONNECTION_KICK_DETECTED, "Tried to kick someone using lost connection kick"},
|
||||
{Infraction::SPOOFED_ROCKSTAR_ID, "Had spoofed RID"},
|
||||
{Infraction::TRIGGERED_ANTICHEAT, "Triggered Rockstar's anticheat"},
|
||||
{Infraction::TRIED_CRASH_PLAYER, "Tried to crash you"},
|
||||
{Infraction::TRIED_KICK_PLAYER, "Tried to kick you"},
|
||||
{Infraction::BLAME_EXPLOSION_DETECTED, "Tried to blame someone for their explosion"},
|
||||
{Infraction::ATTACKING_WITH_GODMODE, "Attacked someone while using godmode"},
|
||||
{Infraction::ATTACKING_WITH_INVISIBILITY, "Attacked someone while being invisible"},
|
||||
{Infraction::ATTACKING_WHEN_HIDDEN_FROM_PLAYER_LIST, "Attacked someone while being hidden from the player list"},
|
||||
{Infraction::SPOOFED_DATA, "Had spoofed data"},
|
||||
{Infraction::SPOOFED_HOST_TOKEN, "Had spoofed their host token"},
|
||||
{Infraction::INVALID_PLAYER_MODEL, "Had used an invalid player model"},
|
||||
{Infraction::SUPER_JUMP, "Had used super jump"},
|
||||
{Infraction::UNDEAD_OTR, "Had used undead OTR"},
|
||||
};
|
||||
|
||||
const char* persistent_player::get_infraction_description(int infraction)
|
||||
{
|
||||
if (static_cast<Infraction>(infraction) == Infraction::CUSTOM_REASON)
|
||||
{
|
||||
return custom_infraction_reason.c_str();
|
||||
}
|
||||
|
||||
return infraction_desc[static_cast<Infraction>(infraction)];
|
||||
}
|
||||
|
||||
std::string persistent_player::get_all_infraction_descriptions()
|
||||
{
|
||||
if (!infractions.size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
constexpr auto separator = ", ";
|
||||
constexpr size_t separator_length = (std::string(separator)).size();
|
||||
|
||||
std::string s;
|
||||
|
||||
for (const auto infr : infractions)
|
||||
{
|
||||
s += get_infraction_description(infr);
|
||||
s += separator;
|
||||
}
|
||||
|
||||
// Remove last useless separator
|
||||
for (size_t i = 0; i < separator_length; i++)
|
||||
{
|
||||
s.pop_back();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "core/data/infractions.hpp"
|
||||
#include "json_util.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
@ -43,12 +42,13 @@ namespace big
|
||||
struct persistent_player
|
||||
{
|
||||
std::string name;
|
||||
uint64_t rockstar_id = 0;
|
||||
bool block_join = false;
|
||||
int block_join_reason = 1;
|
||||
bool is_modder = false;
|
||||
bool notify_online = false;
|
||||
uint64_t rockstar_id = 0;
|
||||
bool block_join = false;
|
||||
int block_join_reason = 1;
|
||||
bool is_modder = false;
|
||||
bool notify_online = false;
|
||||
std::unordered_set<int> infractions;
|
||||
std::string custom_infraction_reason = "";
|
||||
std::string notes = "";
|
||||
std::optional<CommandAccessLevel> command_access_level = std::nullopt;
|
||||
bool join_redirect = false;
|
||||
@ -66,7 +66,9 @@ namespace big
|
||||
std::string game_mode_id = "";
|
||||
rage::rlSessionInfo redirect_info{};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, name, rockstar_id, block_join, block_join_reason, is_modder, notify_online, infractions, notes, command_access_level, join_redirect, join_redirect_preference)
|
||||
};
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, name, rockstar_id, block_join, block_join_reason, is_modder, notify_online, infractions, custom_infraction_reason, notes, command_access_level, join_redirect, join_redirect_preference)
|
||||
|
||||
const char* get_infraction_description(int infraction);
|
||||
std::string get_all_infraction_descriptions();
|
||||
};
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "core/data/infractions.hpp"
|
||||
#include "core/data/session_types.hpp"
|
||||
#include "fiber_pool.hpp"
|
||||
#include "gta/joaat.hpp"
|
||||
@ -48,7 +49,7 @@ namespace big::session
|
||||
else
|
||||
{
|
||||
*scr_globals::session.at(2).as<int*>() = 0;
|
||||
*scr_globals::session2.as<int*>() = (int)session;
|
||||
*scr_globals::session2.as<int*>() = (int)session;
|
||||
}
|
||||
|
||||
*scr_globals::session.as<int*>() = 1;
|
||||
@ -63,7 +64,7 @@ namespace big::session
|
||||
}
|
||||
|
||||
scr_functions::reset_session_data({true, true});
|
||||
*scr_globals::session3.as<int*>() = 0;
|
||||
*scr_globals::session3.as<int*>() = 0;
|
||||
*scr_globals::session4.as<int*>() = 1;
|
||||
*scr_globals::session5.as<int*>() = 32;
|
||||
|
||||
@ -158,7 +159,7 @@ namespace big::session
|
||||
});
|
||||
}
|
||||
|
||||
inline void add_infraction(player_ptr player, Infraction infraction)
|
||||
inline void add_infraction(player_ptr player, Infraction infraction, const std::string& custom_reason = "")
|
||||
{
|
||||
if (g.debug.fuzzer.enabled)
|
||||
return;
|
||||
@ -168,8 +169,15 @@ namespace big::session
|
||||
{
|
||||
plyr->is_modder = true;
|
||||
player->is_modder = true;
|
||||
|
||||
plyr->infractions.insert((int)infraction);
|
||||
if (infraction == Infraction::CUSTOM_REASON)
|
||||
{
|
||||
plyr->custom_infraction_reason += plyr->custom_infraction_reason.size() ? (std::string(", ") + custom_reason) : custom_reason;
|
||||
}
|
||||
|
||||
g_player_database_service->save();
|
||||
|
||||
g.reactions.modder_detection.process(player);
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ namespace big
|
||||
|
||||
for (auto& infraction : current_player->infractions)
|
||||
{
|
||||
ImGui::BulletText(infraction_desc[(Infraction)infraction]);
|
||||
ImGui::BulletText(current_player->get_infraction_description(infraction));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace big
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
for (auto infraction : sorted_player->infractions)
|
||||
ImGui::BulletText(infraction_desc[(Infraction)infraction]);
|
||||
ImGui::BulletText(sorted_player->get_infraction_description(infraction));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user