Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0142e369c9 | ||
|
|
dc79b4b12a | ||
|
|
64b5ea2fba | ||
|
|
808cdfc359 | ||
|
|
4b3c313cef | ||
|
|
b04c2121ba | ||
|
|
2e6c0b05f5 | ||
|
|
88779b3229 | ||
|
|
aa05a066e2 | ||
|
|
53ebd0ebd5 | ||
|
|
9e4f1145f7 | ||
|
|
7b7c697f87 | ||
|
|
82c3412598 | ||
|
|
87fed4bce9 |
@@ -90,7 +90,18 @@ function deleteLocalGameElement(element) {
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function createGameVehicle(modelIndex, position, heading) {
|
function createGameVehicle(modelIndex, position, heading) {
|
||||||
return game.createVehicle(getGameConfig().vehicles[getGame()][modelIndex][0], position, heading);
|
if (getGame() != AGRP_GAME_GTA_IV) {
|
||||||
|
return game.createVehicle(getGameConfig().vehicles[getGame()][modelIndex][0], position, heading);
|
||||||
|
} else {
|
||||||
|
let modelId = getGameConfig().vehicles[getGame()][modelIndex][0];
|
||||||
|
if (natives.isModelInCdimage(modelId)) {
|
||||||
|
natives.requestModel(modelId);
|
||||||
|
natives.loadAllObjectsNow();
|
||||||
|
return natives.createCar(modelId, position, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class VehicleData {
|
|||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function receiveVehicleFromServer(vehicleId, position, model, colour1, colour2, colour3 = 0, colour4 = 0, locked = false, lights = false, engine = false, licensePlate = "") {
|
function receiveVehicleFromServer(vehicleId, networkId, position, model, colour1, colour2, colour3 = 0, colour4 = 0, locked = false, lights = false, engine = false, licensePlate = "") {
|
||||||
logToConsole(LOG_DEBUG, `[VRR.Vehicle] Received vehicle ${vehicleId} (${getVehicleNameFromModel(model, getGame())}) from server`);
|
logToConsole(LOG_DEBUG, `[VRR.Vehicle] Received vehicle ${vehicleId} (${getVehicleNameFromModel(model, getGame())}) from server`);
|
||||||
|
|
||||||
if (getGame() != AGRP_GAME_GTA_IV) {
|
if (getGame() != AGRP_GAME_GTA_IV) {
|
||||||
@@ -50,8 +50,16 @@ function receiveVehicleFromServer(vehicleId, position, model, colour1, colour2,
|
|||||||
vehicleData.lights = lights;
|
vehicleData.lights = lights;
|
||||||
vehicleData.locked = locked;
|
vehicleData.locked = locked;
|
||||||
vehicleData.licensePlate = "";
|
vehicleData.licensePlate = "";
|
||||||
|
vehicleData.networkId = networkId;
|
||||||
|
|
||||||
let vehicle = natives.getVehicleFromNetworkId(vehicleId.ivNetworkId);
|
if (natives.getVehicleFromNetworkId(vehicleId.ivNetworkId) != null) {
|
||||||
|
vehicleData.vehicle = natives.getVehicleFromNetworkId(vehicleId.ivNetworkId);
|
||||||
|
} else {
|
||||||
|
let vehicle = createGameVehicle(model, position, heading, colour1, colour2, colour3, colour4);
|
||||||
|
vehicleData.vehicle = vehicle;
|
||||||
|
|
||||||
|
sendNetworkEventToServer("agrp.vehicleCreated", vehicleId, natives.getNetworkIdFromVehicle(vehicle));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//logToConsole(LOG_DEBUG, `[VRR.Vehicle] Vehicle ${vehicleId} doesn't exist. Adding ...`);
|
//logToConsole(LOG_DEBUG, `[VRR.Vehicle] Vehicle ${vehicleId} doesn't exist. Adding ...`);
|
||||||
//let tempVehicleData = new VehicleData(vehicleId, name, position, blipModel, pickupModel);
|
//let tempVehicleData = new VehicleData(vehicleId, name, position, blipModel, pickupModel);
|
||||||
|
|||||||
@@ -565,72 +565,97 @@ function isVehicleObject(vehicle) {
|
|||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function repairVehicle(vehicle) {
|
function repairVehicle(vehicleIndex) {
|
||||||
vehicle.fix();
|
if (areServerElementsSupported()) {
|
||||||
}
|
getElementFromId(vehicleIndex).vehicle.fix();
|
||||||
|
} else {
|
||||||
// ===========================================================================
|
sendNetworkEventToPlayer("agrp.veh.fix", null, vehicleIndex);
|
||||||
|
|
||||||
function setVehicleLights(vehicle, lights) {
|
|
||||||
setEntityData(vehicle, "agrp.lights", lights, true);
|
|
||||||
sendNetworkEventToPlayer("agrp.veh.lights", null, vehicle.id, lights);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function setVehicleEngine(vehicle, engine) {
|
|
||||||
vehicle.engine = engine;
|
|
||||||
setEntityData(vehicle, "agrp.engine", engine, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function setVehicleLocked(vehicle, locked) {
|
|
||||||
vehicle.locked = locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function setVehicleSiren(vehicle, siren) {
|
|
||||||
vehicle.siren = siren;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function getVehicleLights(vehicle) {
|
|
||||||
return vehicle.lights;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function getVehicleEngine(vehicle) {
|
|
||||||
return vehicle.engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function getVehicleLocked(vehicle) {
|
|
||||||
return vehicle.lockedStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function getVehicleSiren(vehicle) {
|
|
||||||
return vehicle.siren;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
function setVehicleColours(vehicle, colour1, colour2, colour3 = -1, colour4 = -1) {
|
|
||||||
vehicle.colour1 = colour1;
|
|
||||||
vehicle.colour2 = colour2;
|
|
||||||
|
|
||||||
if (colour3 != -1) {
|
|
||||||
vehicle.colour3 = colour3;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (colour4 != -1) {
|
// ===========================================================================
|
||||||
vehicle.colour4 = colour4;
|
|
||||||
|
|
||||||
|
function setVehicleLights(vehicleIndex, lights) {
|
||||||
|
if (areServerElementsSupported()) {
|
||||||
|
setEntityData(getElementFromId(vehicleIndex), "agrp.lights", lights, true);
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.lights", null, vehicleIndex, lights);
|
||||||
|
} else {
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.lights", null, vehicleIndex, lights);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function setVehicleEngine(vehicleIndex, engine) {
|
||||||
|
if (areServerElementsSupported()) {
|
||||||
|
getElementFromId(vehicleIndex).engine = engine;
|
||||||
|
setEntityData(getElementFromId(vehicleIndex), "agrp.engine", engine, true);
|
||||||
|
} else {
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.engine", null, vehicleIndex, engine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function setVehicleLocked(vehicleIndex, locked) {
|
||||||
|
if (areServerElementsSupported()) {
|
||||||
|
getElementFromId(vehicleIndex).vehicle.locked = locked;
|
||||||
|
} else {
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.locked", null, vehicleIndex, locked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function setVehicleSiren(vehicleIndex, siren) {
|
||||||
|
if (areServerElementsSupported()) {
|
||||||
|
getVehicleData(vehicleIndex).vehicle.siren = siren;
|
||||||
|
} else {
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.siren", null, vehicleIndex, siren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function getVehicleLights(vehicleIndex) {
|
||||||
|
return getVehicleData(vehicleIndex).lights;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function getVehicleEngine(vehicleIndex) {
|
||||||
|
return getVehicleData(vehicleIndex).engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function getVehicleLocked(vehicleIndex) {
|
||||||
|
return getVehicleData(vehicleIndex).locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function getVehicleSiren(vehicleIndex) {
|
||||||
|
return getVehicleData(vehicleIndex).siren;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function setVehicleColours(vehicleIndex, colour1, colour2, colour3 = -1, colour4 = -1) {
|
||||||
|
if (areServerElementsSupported()) {
|
||||||
|
getVehicleData(vehicleIndex).vehicle.colour1 = colour1;
|
||||||
|
getVehicleData(vehicleIndex).vehicle.colour2 = colour2;
|
||||||
|
|
||||||
|
if (colour3 != -1) {
|
||||||
|
getVehicleData(vehicleIndex).vehicle.colour3 = colour3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colour4 != -1) {
|
||||||
|
getVehicleData(vehicleIndex).vehicle.colour4 = colour4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendNetworkEventToPlayer("agrp.veh.colours", null, vehicleIndex, colour1, colour2, colour3, colour4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,7 +734,7 @@ function setPlayerFightStyle(client, fightStyleId) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!areFightStylesSupported()) {
|
if (!isGameFeatureSupported("fightStyles")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,8 +1128,8 @@ function getClosestCivilian(position) {
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function getVehiclesInRange(position, range) {
|
function getVehiclesInRange(position, range) {
|
||||||
if (getGame() == AGRP_GAME_GTA_IV) {
|
if (!areServerElementsSupported()) {
|
||||||
return getServerData().vehicles.reduce((i, j) => (getDistance(position, i.syncPosition) <= getDistance(position, j.syncPosition)) ? i : j);
|
return getServerData().vehicles.filter(x => getDistance(position, x.syncPosition) <= distance);
|
||||||
}
|
}
|
||||||
return getElementsByTypeInRange(ELEMENT_VEHICLE, position, range);
|
return getElementsByTypeInRange(ELEMENT_VEHICLE, position, range);
|
||||||
}
|
}
|
||||||
@@ -1112,6 +1137,9 @@ function getVehiclesInRange(position, range) {
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function getClosestVehicle(position) {
|
function getClosestVehicle(position) {
|
||||||
|
if (!areServerElementsSupported()) {
|
||||||
|
getServerData().vehicles.reduce((i, j) => (getDistance(position, i.syncPosition) <= getDistance(position, j.syncPosition)) ? i : j);
|
||||||
|
}
|
||||||
return getClosestElementByType(ELEMENT_VEHICLE, position);
|
return getClosestElementByType(ELEMENT_VEHICLE, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ function addAllNetworkEventHandlers() {
|
|||||||
addNetworkEventHandler("agrp.vehBuyState", receiveVehiclePurchaseStateUpdateFromClient);
|
addNetworkEventHandler("agrp.vehBuyState", receiveVehiclePurchaseStateUpdateFromClient);
|
||||||
addNetworkEventHandler("agrp.playerPedId", receivePlayerPedNetworkId);
|
addNetworkEventHandler("agrp.playerPedId", receivePlayerPedNetworkId);
|
||||||
addNetworkEventHandler("agrp.playerCop", setPlayerAsCopState);
|
addNetworkEventHandler("agrp.playerCop", setPlayerAsCopState);
|
||||||
|
|
||||||
|
addNetworkEventHandler("agrp.vehicleSpawned", vehicleSpawnedByPlayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -130,9 +132,9 @@ function playerClientStarted(client) {
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
function playerClientStopped(client) {
|
function playerClientStopped(client) {
|
||||||
logToConsole(LOG_DEBUG, `[VRR.Client] ${getPlayerDisplayForConsole(client)}'s client resources have stopped (possibly error?). Kicking them from the server ...`);
|
//logToConsole(LOG_DEBUG, `[VRR.Client] ${getPlayerDisplayForConsole(client)}'s client resources have stopped (possibly error?). Kicking them from the server ...`);
|
||||||
getPlayerData(targetClient).customDisconnectReason = `Kicked - Client script verification failed. Possible hacks.`;
|
//getPlayerData(client).customDisconnectReason = `Kicked - Client script verification failed. Possible hacks.`;
|
||||||
disconnectPlayer(client);
|
//disconnectPlayer(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -1114,7 +1116,7 @@ function sendJobToPlayer(client, jobId, jobLocationId, name, position) {
|
|||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
function sendVehicleToPlayer(client, vehicleId, model, position, heading, colour1, colour2, colour3, colour4) {
|
function sendVehicleToPlayer(client, vehicleId, networkId, model, position, heading, colour1, colour2, colour3, colour4) {
|
||||||
sendNetworkEventToPlayer("agrp.vehicle", client, vehicleId, model, position, heading, colour1, colour2, colour3, colour4);
|
sendNetworkEventToPlayer("agrp.vehicle", client, vehicleId, model, position, heading, colour1, colour2, colour3, colour4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,7 +1154,7 @@ function sendAllJobsToPlayer(client) {
|
|||||||
function sendAllVehiclesToPlayer(client) {
|
function sendAllVehiclesToPlayer(client) {
|
||||||
let vehicles = getServerData().vehicles;
|
let vehicles = getServerData().vehicles;
|
||||||
for (let i in vehicles) {
|
for (let i in vehicles) {
|
||||||
sendVehicleToPlayer(client, vehicles[i].index, vehicles[i].model, vehicles[i].syncPosition, vehicles[i].syncHeading, vehicles[i].colour1, vehicles[i].colour2, vehicles[i].colour3, vehicles[i].colour4);
|
sendVehicleToPlayer(client, vehicles[i].index, vehicles[i].ivNetworkId, vehicles[i].model, vehicles[i].syncPosition, vehicles[i].syncHeading, vehicles[i].colour1, vehicles[i].colour2, vehicles[i].colour3, vehicles[i].colour4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -472,4 +472,24 @@ function updateAllPlayerWeaponDamageStates() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function moveAllPlayersToNewLobby(hostClient) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function resetPlayerForLobbySwitch(client) {
|
||||||
|
clearPlayerWeapons(client);
|
||||||
|
setPlayerPosition(client, getPlayerData(client).syncPosition);
|
||||||
|
setPlayerHeading(client, getPlayerData(client).syncHeading);
|
||||||
|
//setPlayerInterior(client, spawnInterior);
|
||||||
|
//setPlayerDimension(client, spawnDimension);
|
||||||
|
restorePlayerCamera(client);
|
||||||
|
setPlayerSkin(client, getPlayerCurrentSubAccount(client).skin);
|
||||||
|
|
||||||
|
onPlayerSpawn(client);
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -1890,4 +1890,10 @@ function isPlayerInVehicleDriverSeat(client) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
function vehicleSpawnedByPlayer(client, vehicleIndex, networkId) {
|
||||||
|
getVehicleData(vehicleIndex).ivNetworkId = networkId;
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -138,3 +138,8 @@ const AGRP_NPC_ACTION_SPRINTTO = 4;
|
|||||||
const AGRP_NPC_ACTION_FOLLOW = 5;
|
const AGRP_NPC_ACTION_FOLLOW = 5;
|
||||||
const AGRP_NPC_ACTION_DEFEND = 6;
|
const AGRP_NPC_ACTION_DEFEND = 6;
|
||||||
const AGRP_NPC_ACTION_GUARD_AREA = 7;
|
const AGRP_NPC_ACTION_GUARD_AREA = 7;
|
||||||
|
|
||||||
|
// Body Part Types (for HD universe GTA games)
|
||||||
|
const AGRP_BODY_PART_TYPE_NONE = 0; // None
|
||||||
|
const AGRP_BODY_PART_TYPE_PART = 1; // Body part (head, upper body, lower body, etc)
|
||||||
|
const AGRP_BODY_PART_TYPE_PROP = 2; // Prop (hat, watch, glasses, etc)
|
||||||
@@ -174,8 +174,8 @@ let supportedFeatures = {
|
|||||||
[AGRP_GAME_GTA_III]: true,
|
[AGRP_GAME_GTA_III]: true,
|
||||||
[AGRP_GAME_GTA_VC]: true,
|
[AGRP_GAME_GTA_VC]: true,
|
||||||
[AGRP_GAME_GTA_SA]: true,
|
[AGRP_GAME_GTA_SA]: true,
|
||||||
[AGRP_GAME_GTA_IV]: false,
|
[AGRP_GAME_GTA_IV]: true,
|
||||||
[AGRP_GAME_GTA_IV]: false,
|
[AGRP_GAME_GTA_IV]: true,
|
||||||
[AGRP_GAME_GTA_IV_EFLC]: false,
|
[AGRP_GAME_GTA_IV_EFLC]: false,
|
||||||
[AGRP_GAME_MAFIA_ONE]: false,
|
[AGRP_GAME_MAFIA_ONE]: false,
|
||||||
[AGRP_GAME_MAFIA_TWO]: false,
|
[AGRP_GAME_MAFIA_TWO]: false,
|
||||||
@@ -202,8 +202,8 @@ let supportedFeatures = {
|
|||||||
[AGRP_GAME_MAFIA_THREE]: false
|
[AGRP_GAME_MAFIA_THREE]: false
|
||||||
},
|
},
|
||||||
pedScale: {
|
pedScale: {
|
||||||
[AGRP_GAME_GTA_III]: false,
|
[AGRP_GAME_GTA_III]: true,
|
||||||
[AGRP_GAME_GTA_VC]: false,
|
[AGRP_GAME_GTA_VC]: true,
|
||||||
[AGRP_GAME_GTA_SA]: false,
|
[AGRP_GAME_GTA_SA]: false,
|
||||||
[AGRP_GAME_GTA_IV]: false,
|
[AGRP_GAME_GTA_IV]: false,
|
||||||
[AGRP_GAME_GTA_IV_EFLC]: false,
|
[AGRP_GAME_GTA_IV_EFLC]: false,
|
||||||
@@ -215,8 +215,8 @@ let supportedFeatures = {
|
|||||||
[AGRP_GAME_GTA_III]: true,
|
[AGRP_GAME_GTA_III]: true,
|
||||||
[AGRP_GAME_GTA_VC]: true,
|
[AGRP_GAME_GTA_VC]: true,
|
||||||
[AGRP_GAME_GTA_SA]: true,
|
[AGRP_GAME_GTA_SA]: true,
|
||||||
[AGRP_GAME_GTA_IV]: true,
|
[AGRP_GAME_GTA_IV]: false,
|
||||||
[AGRP_GAME_GTA_IV_EFLC]: true,
|
[AGRP_GAME_GTA_IV_EFLC]: false,
|
||||||
[AGRP_GAME_MAFIA_ONE]: false,
|
[AGRP_GAME_MAFIA_ONE]: false,
|
||||||
[AGRP_GAME_MAFIA_TWO]: false,
|
[AGRP_GAME_MAFIA_TWO]: false,
|
||||||
[AGRP_GAME_MAFIA_THREE]: false
|
[AGRP_GAME_MAFIA_THREE]: false
|
||||||
@@ -6706,6 +6706,14 @@ let gameData = {
|
|||||||
GunMuzzleFlashStays: 20,
|
GunMuzzleFlashStays: 20,
|
||||||
SingleSparking: 21,
|
SingleSparking: 21,
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
bodyParts: {
|
||||||
|
[AGRP_GAME_GTA_IV]: {
|
||||||
|
[AGRP_SKINSELECT_HEAD]: { LocaleStringIndex: "Head", Type: AGRP_BODY_PART_TYPE_PART, Slot: 0 },
|
||||||
|
[AGRP_SKINSELECT_UPPER]: { LocaleStringIndex: "UpperBody", Type: AGRP_BODY_PART_TYPE_PART, Slot: 1 },
|
||||||
|
[AGRP_SKINSELECT_LOWER]: { LocaleStringIndex: "LowerBody", Type: AGRP_BODY_PART_TYPE_PART, Slot: 2 },
|
||||||
|
[AGRP_SKINSELECT_HAT]: { LocaleStringIndex: "Hat", Type: AGRP_BODY_PART_TYPE_PROP, Slot: 0 },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user