diff --git a/files/images/server-logo.png b/files/images/server-logo.png
new file mode 100644
index 00000000..00d67502
Binary files /dev/null and b/files/images/server-logo.png differ
diff --git a/locale/chinese.json b/locale/chinese.json
index c07ea0c2..57eab3d4 100644
--- a/locale/chinese.json
+++ b/locale/chinese.json
@@ -387,5 +387,9 @@
"TimeNotNumber": "The time must be a number",
"HeaderDefaultBusinessItemTypes": "Business Item Templates",
"FixingStuck": "Fixing your position and virtual world ...",
- "CantUseCommandYet": "You must wait before you can use this command again!"
+ "CantUseCommandYet": "You must wait before you can use this command again!",
+ "NotATester": "You are not a tester!",
+ "AccessDenied": "AccessDenied",
+ "InvalidSkin": "That skin is invalid!",
+ "HeaderInteriorTypes": "Interiors"
}
diff --git a/locale/english.json b/locale/english.json
index 6eba14da..db17cb30 100644
--- a/locale/english.json
+++ b/locale/english.json
@@ -387,5 +387,9 @@
"TimeNotNumber": "The time must be a number",
"HeaderDefaultBusinessItemTypes": "Business Item Templates",
"FixingStuck": "Fixing your position and virtual world ...",
- "CantUseCommandYet": "You must wait before you can use this command again!"
+ "CantUseCommandYet": "You must wait before you can use this command again!",
+ "NotATester": "You are not a tester!",
+ "AccessDenied": "AccessDenied",
+ "InvalidSkin": "That skin is invalid!",
+ "HeaderInteriorTypes": "Interiors"
}
diff --git a/locale/polish.json b/locale/polish.json
index c9f470c2..02a57f7c 100644
--- a/locale/polish.json
+++ b/locale/polish.json
@@ -387,5 +387,9 @@
"TimeNotNumber": "The time must be a number",
"HeaderDefaultBusinessItemTypes": "Business Item Templates",
"FixingStuck": "Fixing your position and virtual world ...",
- "CantUseCommandYet": "You must wait before you can use this command again!"
+ "CantUseCommandYet": "You must wait before you can use this command again!",
+ "NotATester": "You are not a tester!",
+ "AccessDenied": "AccessDenied",
+ "InvalidSkin": "That skin is invalid!",
+ "HeaderInteriorTypes": "Interiors"
}
diff --git a/locale/russian.json b/locale/russian.json
index 88cf1f21..b9a0ade7 100644
--- a/locale/russian.json
+++ b/locale/russian.json
@@ -320,71 +320,75 @@
},
"ADDED-21JAN2022": "DO NOT TRANSLATE. This string is just a comment to separate newly added translations.",
- "HeaderPlayerHousesList": "Player Houses ({1})",
- "HeaderPlayerStaffFlagsList": "Player Staff Flags ({1})",
- "HeaderStaffFlagsList": "Staff Flags",
- "NonRPName": "Non-RP name! Choose a new one:",
- "InvalidStaffFlag": "Staff flag not found!",
- "InvalidClanFlag": "Clan flag not found!",
- "InvalidLocale": "Language not found!",
- "HeaderJobUniformList": "Job Uniforms ({1})",
- "HeaderJobEquipmentList": "Job Equipment ({1})",
- "InvalidJobUniform": "Job uniform not found!",
- "InvalidJobEquipment": "Job equipment not found!",
- "HeaderVehiclesInRangeList": "Vehicles within {1}",
- "NoVehiclesWithInRange": "There are no vehicles within {1}",
- "AmountNotNumber": "The amount must be a number!",
- "NeedToBeWorking": "You need to be working! Use {1} at a job location or near a job vehicle.",
- "NeedToBeOnJobRoute": "You need to be doing a job route! Use {1} in a job vehicle",
- "CurrentJobRouteDeleted": "The job route you were on has been deleted by an admin",
- "CurrentJobRouteVehicleColoursChanged": "Your job route's vehicle colours were changed by an admin",
- "NotYourJob": "This is not your job!",
- "JobPoints": "You can get a job by going the yellow points on the map.",
- "QuitJobToTakeAnother": "If you want this job, use {1} to quit your current job.",
- "NotAJobVehicle": "This is not a job vehicle!",
- "NotYourJobVehicle": "This is not your job's vehicle!",
- "JobRouteDisabled": "The job route you were on has been disabled by an admin",
- "HeaderPickupTypes": "Pickup Types",
- "HeaderBlipTypes": "Map Icon Types",
- "InvalidGPSLocation": "There are no locations with that name or type",
- "HeaderBusinessList": "Businesses",
- "VehicleForSale": "This {1} is buyable for {2}! Use {3} if you want to buy it",
- "VehicleForRent": "This {1} is rentable for {2}! Use {3} if you want to rent it",
+ "HeaderPlayerHousesList": "Дома Игрока ({1})",
+ "HeaderPlayerStaffFlagsList": "Флаги игрока персонала ({1})",
+ "HeaderStaffFlagsList": "Флаги персонала",
+ "NonRPName": "Ваше имя не подходит для ролевой игры! Выберете другое:",
+ "InvalidStaffFlag": "Не удалось найти флаг персонала!",
+ "InvalidClanFlag": "Не удалось найти флаг клана!",
+ "InvalidLocale": "Не удалось найти язык!",
+ "HeaderJobUniformList": "Рабочие униформы ({1})",
+ "HeaderJobEquipmentList": "Рабочие снаряжение ({1})",
+ "InvalidJobUniform": "Не удалось найти рабочую униформу!",
+ "InvalidJobEquipment": "Не удалось найти рабочее снаряжение!",
+ "HeaderVehiclesInRangeList": "Транспорт в пределах {1}",
+ "NoVehiclesWithInRange": "Нет транспорта в пределах {1}",
+ "AmountNotNumber": "Количество должно быть введено цифрой!",
+ "NeedToBeWorking": "Вы должны быть на работе! Используйте {1} на месте работы или возле рабочего транспорта.",
+ "NeedToBeOnJobRoute": "Вы должны быть на рабочем маршруте! Используйте {1} в рабочем транспорте",
+ "CurrentJobRouteDeleted": "Рабочий маршрут на котором вы находились был удален администратором",
+ "CurrentJobRouteVehicleColoursChanged": "Цвет транспорта на маршруте был изменен администратором",
+ "NotYourJob": "Это работа пренадлежит не вам!",
+ "JobPoints": "Вы можете устроиться на работу ориентируясь по желтым значкам на карте.",
+ "QuitJobToTakeAnother": "Если хотите покинуть работу, ипользуйте {1}.",
+ "NotAJobVehicle": "Это не рабочий транспорт!",
+ "NotYourJobVehicle": "Этот транспорт пренадлежит не вашей работе!",
+ "JobRouteDisabled": "Рабочий маршрут на котором вы были был удален администратором",
+ "HeaderPickupTypes": "Типы подбираемых предметов",
+ "HeaderBlipTypes": "Типы иконок карты",
+ "InvalidGPSLocation": "Не существует локаций с таки именем или такого типа",
+ "HeaderBusinessList": "Бизнесы",
+ "VehicleForSale": "Этот {1} можно купить за {2}! Используйте {3} если хотите его купить",
+ "VehicleForRent": "Этот {1} может быть орендован за {2}! Используйте {3} если хотите его орендовать",
"ADDED-31JAN2022": "DO NOT TRANSLATE. This string is just a comment to separate newly added translations.",
- "LoginFailedInvalidPassword": "Invalid password! {1} attempts remaining",
- "LoginFailedNoPassword": "You must enter a password! ! {1} attempts remaining",
- "RegistrationFailedNoPassword": "You must enter a password!",
- "RegistrationFailedNoPasswordConfirm": "You must confirm the password!",
- "RegistrationFailedNoEmail": "You must enter an email!",
- "AccountNameAlreadyRegistered": "Your name is already registered!",
- "AlreadyLoggedIn": "You are already logged in!",
- "RegistrationFailedInvalidEmail": "That email is invalid!",
- "RegistrationFailedPasswordMismatch": "The passwords don't match!",
- "RegistrationFailedCreateError": "Your account couldn't be created!",
- "RegistrationSuccess": "Your account has been created!",
- "RegistrationEmailVerifyReminder": "Don't forget to verify your email! A verification code has been sent to you.",
- "RegistrationCreateCharReminder": "To play on the server, you will need to make a character.",
- "NoCharactersGUIMessage": "You have no characters. Would you like to make one?",
- "NoCharactersGUIWindowTitle": "No characters",
- "NoCharactersChatMessage": "You have no characters. Use {1} to make one.",
- "NeedEmailFor2FA": "You need to add your email to your account to use two-factor authentication.",
- "NeedEmailVerifiedFor2FA": "You need to verify your email to use two-factor authentication.",
- "SetEmailHelpTip": "Use {1} to set your email.",
- "VerifyEmailHelpTip": "Use {1} to verify your email.",
+ "LoginFailedInvalidPassword": "Неправельный пароль! Осталось {1} попыток",
+ "LoginFailedNoPassword": "Вы должны ввести пароль! Осталось {1} попыток",
+ "RegistrationFailedNoPassword": "Вы должны ввести пароль!",
+ "RegistrationFailedNoPasswordConfirm": "Вы должны подтвердить пароль!",
+ "RegistrationFailedNoEmail": "Вы должны ввести адрес электронной почты!",
+ "AccountNameAlreadyRegistered": "Ваше имя уже зарегистрировано!",
+ "AlreadyLoggedIn": "Вы уже вошли!",
+ "RegistrationFailedInvalidEmail": "Такого адреса не существует!",
+ "RegistrationFailedPasswordMismatch": "Пароли не совпадают!",
+ "RegistrationFailedCreateError": "Не удалось создать аккаунт!",
+ "RegistrationSuccess": "Ваш аккаунт был успешно создан!",
+ "RegistrationEmailVerifyReminder": "Не забудьте подтвердить ваш электронный адрес, код подверждения был послан вам на электронную почту.",
+ "RegistrationCreateCharReminder": "Чтобы играть на сервере, вам нужно будет создать персонажа.",
+ "NoCharactersGUIMessage": "У вас нет персонажей. Не хотите создать?",
+ "NoCharactersGUIWindowTitle": "Нет персонажей",
+ "NoCharactersChatMessage": "У вас нет персонажей. Используйте {1} чтобы создать.",
+ "NeedEmailFor2FA": "Вам нужно добавить ваш адрес электронной почты чтобы использовать двухфакторную аунтентификацию.",
+ "NeedEmailVerifiedFor2FA": "Вам нужно подтвердить вашу электронную почту чтобы использовать двухфакторную аунтентификацию.",
+ "SetEmailHelpTip": "Используйте {1} чтобы установить ваш адрес электронной почты.",
+ "VerifyEmailHelpTip": "Используйте {1} чтобы подтвердить ваш адрес электронной почты.",
"ADDED-13FEB2022": "DO NOT TRANSLATE. This string is just a comment to separate newly added translations.",
- "NearbyRadio": "Nearby radio",
- "FromRadio": "From radio",
- "ToRadio": "To radio",
- "NeedToEnterPropertyCommand": "You need to enter the {1} first! Use {2} to enter and exit",
- "NeedToEnterPropertyKeyPress": "You need to enter the {1} first! Press {2} to enter and exit",
- "InventoryFullCantCarry": "You don't have any space to carry this (full inventory)!",
- "NotEnoughCashNeedAmountMore": "You don't have enough money! You need {1} more!",
- "AmountMustBeMoreThan": "The amount must be more than {1}!",
- "WeaponBanned": "You are not allowed to buy or use weapons!",
- "TimeNotNumber": "The time must be a number",
- "HeaderDefaultBusinessItemTypes": "Business Item Templates",
- "FixingStuck": "Fixing your position and virtual world ...",
- "CantUseCommandYet": "You must wait before you can use this command again!"
+ "NearbyRadio": "Ближайшее радио",
+ "FromRadio": "Из радио",
+ "ToRadio": "В радио",
+ "NeedToEnterPropertyCommand": "Вам нужно сначало ввести {1}! Используйте {2} чтобы выйти",
+ "NeedToEnterPropertyKeyPress": "Вам нужно сначало ввести {1}! Используйте {2} чтобы выйти",
+ "InventoryFullCantCarry": "У вас недостаточно места в инвентаре(Инвентарь заполнен)!",
+ "NotEnoughCashNeedAmountMore": "У вас недостаточно денег! У вас не хватает {1}!",
+ "AmountMustBeMoreThan": "Количество должно быть больше {1}!",
+ "WeaponBanned": "Вам нельзя покупать оружие!",
+ "TimeNotNumber": "Время должно быть назначено цифрой",
+ "HeaderDefaultBusinessItemTypes": "Шаблоны предметов бизнеса",
+ "FixingStuck": "Исправляет вашу текущую позицию и виртуальный мир ...",
+ "CantUseCommandYet": "Подождите некоторое время перед тем как использовать комманду снова!",
+ "NotATester": "Вы не тестировщик!",
+ "AccessDenied": "Доступ запрещен",
+ "InvalidSkin": "That skin is invalid!",
+ "HeaderInteriorTypes": "Interiors"
}
diff --git a/locale/spanish.json b/locale/spanish.json
index cbd83f01..070a9811 100644
--- a/locale/spanish.json
+++ b/locale/spanish.json
@@ -391,5 +391,9 @@
"TimeNotNumber": "The time must be a number",
"HeaderDefaultBusinessItemTypes": "Business Item Templates",
"FixingStuck": "Fixing your position and virtual world ...",
- "CantUseCommandYet": "You must wait before you can use this command again!"
+ "CantUseCommandYet": "You must wait before you can use this command again!",
+ "NotATester": "You are not a tester!",
+ "AccessDenied": "AccessDenied",
+ "InvalidSkin": "That skin is invalid!",
+ "HeaderInteriorTypes": "Interiors"
}
diff --git a/meta.xml b/meta.xml
index e41b8fd1..1d3ed971 100644
--- a/meta.xml
+++ b/meta.xml
@@ -9,6 +9,7 @@
+
@@ -93,6 +94,7 @@
+
@@ -111,11 +113,9 @@
-
-
-
+
@@ -123,16 +123,17 @@
+
-
+
-
+
diff --git a/scripts/client/animation.js b/scripts/client/animation.js
index 044d3899..2d5760e5 100644
--- a/scripts/client/animation.js
+++ b/scripts/client/animation.js
@@ -56,14 +56,18 @@ function makePedStopAnimation(pedId) {
return false;
}
- if(getGame() == VRR_GAME_GTA_VC || getGame() == VRR_GAME_GTA_SA) {
- getElementFromId(pedId).clearAnimations();
- } else {
- getElementFromId(pedId).clearObjective();
+ if(getGame() != VRR_GAME_GTA_IV) {
+ if(getGame() == VRR_GAME_GTA_VC || getGame() == VRR_GAME_GTA_SA) {
+ getElementFromId(pedId).clearAnimations();
+ } else {
+ getElementFromId(pedId).clearObjective();
+ }
}
if(getElementFromId(pedId) == localPlayer) {
- localPlayer.collisionsEnabled = true;
+ if(getGame() != VRR_GAME_GTA_IV) {
+ localPlayer.collisionsEnabled = true;
+ }
setLocalPlayerControlState(true, false);
}
}
diff --git a/scripts/client/content.js b/scripts/client/content.js
index d09d8074..214655ea 100644
--- a/scripts/client/content.js
+++ b/scripts/client/content.js
@@ -8,7 +8,7 @@
// ===========================================================================
function getCustomImage(imageName) {
- let contentResource = findResourceByName(getGameData().extraContentResource[getGame()]);
+ let contentResource = findResourceByName(getGameConfig().extraContentResource[getGame()]);
if(contentResource != null) {
if(contentResource.isStarted) {
let image = contentResource.exports.getCustomImage(imageName);
@@ -23,7 +23,7 @@ function getCustomImage(imageName) {
// ===========================================================================
function getCustomFont(fontName) {
- let contentResource = findResourceByName(getGameData().extraContentResource[getGame()]);
+ let contentResource = findResourceByName(getGameConfig().extraContentResource[getGame()]);
if(contentResource != null) {
if(contentResource.isStarted) {
let font = contentResource.exports.getCustomFont(fontName);
@@ -38,7 +38,7 @@ function getCustomFont(fontName) {
// ===========================================================================
function getCustomAudio(audioName) {
- let contentResource = findResourceByName(getGameData().extraContentResource[getGame()]);
+ let contentResource = findResourceByName(getGameConfig().extraContentResource[getGame()]);
if(contentResource != null) {
if(contentResource.isStarted) {
let audioFile = contentResource.exports.getCustomAudio(audioName);
@@ -53,7 +53,7 @@ function getCustomAudio(audioName) {
// ===========================================================================
function playCustomAudio(audioName, volume = 0.5, loop = false) {
- let contentResource = findResourceByName(getGameData().extraContentResource[getGame()]);
+ let contentResource = findResourceByName(getGameConfig().extraContentResource[getGame()]);
if(contentResource != null) {
if(contentResource.isStarted) {
contentResource.exports.playCustomAudio(audioName, volume, loop);
diff --git a/scripts/client/gui.js b/scripts/client/gui.js
index 59707239..86bd4cf3 100644
--- a/scripts/client/gui.js
+++ b/scripts/client/gui.js
@@ -91,7 +91,7 @@ function initGUI() {
// ===========================================================================
-let closeAllWindows = function() {
+function closeAllWindows() {
logToConsole(LOG_DEBUG, `[VRR.GUI] Closing all GUI windows`);
infoDialog.window.shown = false;
yesNoDialog.window.shown = false;
@@ -104,6 +104,7 @@ let closeAllWindows = function() {
listDialog.window.shown = false;
resetPassword.window.shown = false;
passwordChange.window.shown = false;
+
mexui.setInput(false);
mexui.focusedControl = false;
@@ -116,7 +117,7 @@ let closeAllWindows = function() {
// ===========================================================================
-let isAnyGUIActive = function() {
+function isAnyGUIActive() {
if(!guiReady) {
return false;
}
@@ -299,14 +300,22 @@ function processGUIKeyPress(keyCode) {
if(guiSubmitKey != false) {
guiSubmitKey();
}
- } else if(keyCode == SDLK_LEFT) {
+ } else if(keyCode == getKeyIdFromParams("left") || keyCode == getKeyIdFromParams("a")) {
if(guiLeftKey != false) {
guiLeftKey();
}
- } else if(keyCode == SDLK_RIGHT) {
+ } else if(keyCode == getKeyIdFromParams("right") || keyCode == getKeyIdFromParams("d")) {
if(guiRightKey != false) {
guiRightKey();
}
+ } else if(keyCode == getKeyIdFromParams("down") || keyCode == getKeyIdFromParams("s")) {
+ if(guiDownKey != false) {
+ guiDownKey();
+ }
+ } else if(keyCode == getKeyIdFromParams("up") || keyCode == getKeyIdFromParams("w")) {
+ if(guiUpKey != false) {
+ guiUpKey();
+ }
}
}
diff --git a/scripts/client/gui/clanmgr.js b/scripts/client/gui/clanmgr.js
index 54d33359..631635dd 100644
--- a/scripts/client/gui/clanmgr.js
+++ b/scripts/client/gui/clanmgr.js
@@ -15,4 +15,6 @@ let clanManager = {
vehiclesTab: null,
businessesTab: null,
housesTab: null,
-};
\ No newline at end of file
+};
+
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/client/gui/error.js b/scripts/client/gui/error.js
index 2c6826bb..25315568 100644
--- a/scripts/client/gui/error.js
+++ b/scripts/client/gui/error.js
@@ -46,7 +46,7 @@ function initErrorDialogGUI() {
},
});
- errorDialog.okayButton = errorDialog.window.button(5, 105, 395, 30, 'OK', {
+ errorDialog.okayButton = errorDialog.window.button(5, 105, 390, 30, 'OK', {
main: {
backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(primaryTextColour[0], primaryTextColour[1], primaryTextColour[2], 255),
diff --git a/scripts/client/gui/info.js b/scripts/client/gui/info.js
index bbbb3766..7ecff81b 100644
--- a/scripts/client/gui/info.js
+++ b/scripts/client/gui/info.js
@@ -45,7 +45,7 @@ function initInfoDialogGUI() {
},
});
- infoDialog.okayButton = infoDialog.window.button(5, 105, 395, 30, 'OK', {
+ infoDialog.okayButton = infoDialog.window.button(5, 105, 390, 30, 'OK', {
main: {
backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(primaryTextColour[0], primaryTextColour[1], primaryTextColour[2], 255),
diff --git a/scripts/client/gui/login.js b/scripts/client/gui/login.js
index 60f4b15f..51b5fa03 100644
--- a/scripts/client/gui/login.js
+++ b/scripts/client/gui/login.js
@@ -22,7 +22,7 @@ let login = {
function initLoginGUI() {
logToConsole(LOG_DEBUG, `[VRR.GUI] Creating login GUI ...`);
- login.window = mexui.window(game.width/2-150, game.height/2-130, 300, 260, 'LOGIN', {
+ login.window = mexui.window(game.width/2-150, game.height/2-135, 300, 275, 'LOGIN', {
main: {
backgroundColour: toColour(secondaryColour[0], secondaryColour[1], secondaryColour[2], windowAlpha),
transitionTime: 500,
@@ -42,7 +42,7 @@ function initLoginGUI() {
login.window.titleBarIconSize = toVector2(0,0);
login.window.titleBarHeight = 0;
- login.logoImage = login.window.image(5, 20, 290, 80, mainLogoPath, {
+ login.logoImage = login.window.image(5, 20, 290, 100, mainLogoPath, {
focused: {
borderColour: toColour(0, 0, 0, 0),
},
@@ -168,4 +168,6 @@ function switchToPasswordResetGUI() {
logToConsole(LOG_DEBUG, `[VRR.GUI] Showing password reset dialog window`);
showResetPasswordGUI();
return false;
-}
\ No newline at end of file
+}
+
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/client/gui/newchar.js b/scripts/client/gui/newchar.js
index 8de5c579..fa7ff169 100644
--- a/scripts/client/gui/newchar.js
+++ b/scripts/client/gui/newchar.js
@@ -21,7 +21,7 @@ let newCharacter = {
function initNewCharacterGUI() {
logToConsole(LOG_DEBUG, `[VRR.GUI] Creating new character GUI ...`);
- newCharacter.window = mexui.window(game.width/2-130, game.height/2-100, 300, 200, 'New Character', {
+ newCharacter.window = mexui.window(game.width/2-130, game.height/2-115, 300, 230, 'New Character', {
main: {
backgroundColour: toColour(secondaryColour[0], secondaryColour[1], secondaryColour[2], windowAlpha),
transitionTime: 500,
@@ -46,7 +46,7 @@ function initNewCharacterGUI() {
},
});
- newCharacter.messageLabel = newCharacter.window.text(20, 75, 260, 20, 'Name your character', {
+ newCharacter.messageLabel = newCharacter.window.text(20, 100, 260, 20, 'Name your character', {
main: {
textSize: 10.0,
textAlign: 0.5,
@@ -58,7 +58,7 @@ function initNewCharacterGUI() {
},
});
- newCharacter.firstNameInput = newCharacter.window.textInput(20, 100, 260, 25, '', {
+ newCharacter.firstNameInput = newCharacter.window.textInput(20, 125, 260, 25, '', {
main: {
backgroundColour: toColour(0, 0, 0, 120),
textColour: toColour(200, 200, 200, 255),
@@ -77,7 +77,7 @@ function initNewCharacterGUI() {
});
newCharacter.firstNameInput.placeholder = "First Name";
- newCharacter.lastNameInput = newCharacter.window.textInput(20, 130, 260, 25, '', {
+ newCharacter.lastNameInput = newCharacter.window.textInput(20, 155, 260, 25, '', {
main: {
backgroundColour: toColour(0, 0, 0, 120),
textColour: toColour(200, 200, 200, 255),
@@ -96,7 +96,7 @@ function initNewCharacterGUI() {
});
newCharacter.lastNameInput.placeholder = "Last Name";
- newCharacter.createCharacterButton = newCharacter.window.button(20, 160, 260, 25, 'CREATE CHARACTER', {
+ newCharacter.createCharacterButton = newCharacter.window.button(20, 185, 260, 25, 'CREATE CHARACTER', {
main: {
backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(255, 255, 255, 255),
diff --git a/scripts/client/job.js b/scripts/client/job.js
index ed07737f..c993aa16 100644
--- a/scripts/client/job.js
+++ b/scripts/client/job.js
@@ -90,4 +90,6 @@ function hideJobRouteLocation() {
destroyElement(jobRouteLocationBlip);
jobRouteLocationSphere = null;
jobRouteLocationBlip = null;
-}
\ No newline at end of file
+}
+
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/client/native/connected.js b/scripts/client/native/connected.js
index 69335fb2..f62b24bc 100644
--- a/scripts/client/native/connected.js
+++ b/scripts/client/native/connected.js
@@ -52,7 +52,7 @@ function deleteGameElement(element, position) {
// ===========================================================================
function createGameVehicle(modelIndex, position, heading) {
- return game.createVehicle(getGameData().vehicles[getGame()][modelIndex][0], position, heading);
+ return game.createVehicle(getGameConfig().vehicles[getGame()][modelIndex][0], position, heading);
}
// ===========================================================================
diff --git a/scripts/client/server.js b/scripts/client/server.js
index a74df6f0..b5bb5da8 100644
--- a/scripts/client/server.js
+++ b/scripts/client/server.js
@@ -82,6 +82,7 @@ function addAllNetworkHandlers() {
addNetworkEventHandler("vrr.pedAnim", makePedPlayAnimation);
addNetworkEventHandler("vrr.pedStopAnim", makePedStopAnimation);
+ addNetworkEventHandler("vrr.localPlayerSkin", setLocalPlayerSkin);
addNetworkEventHandler("vrr.forcePedAnim", forcePedAnimation);
addNetworkEventHandler("vrr.hideAllGUI", hideAllGUI);
addNetworkEventHandler("vrr.gameScript", setGameScriptState);
@@ -128,10 +129,12 @@ function setPlayer2DRendering(hudState, labelState, smallGameMessageState, score
logToConsole(LOG_DEBUG, `[VRR.Main] Updating render states (HUD: ${hudState}, Labels: ${labelState}, Bottom Text: ${smallGameMessageState}, Scoreboard: ${scoreboardState}, HotBar: ${hotBarState}, Item Action Delay: ${itemActionDelayState})`);
renderHUD = hudState;
- if(typeof setHUDEnabled != "undefined") {
- if(getGame() == VRR_GAME_GTA_IV) {
- natives.displayHud(false);
- } else {
+ if(getGame() == VRR_GAME_GTA_IV) {
+ natives.displayCash(hudState);
+ natives.displayAmmo(hudState);
+ natives.displayHud(hudState);
+ } else {
+ if(typeof setHUDEnabled != "undefined") {
setHUDEnabled(hudState);
}
}
@@ -297,4 +300,15 @@ function setLocalPlayerInfiniteRun(state) {
}
}
+// ===========================================================================
+
+function setLocalPlayerSkin(skinId) {
+ if(getGame() == VRR_GAME_GTA_IV) {
+ //natives.changePlayerModel(natives.getPlayerId(), skinId);
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ } else {
+ localPlayer.skin = skinId;
+ }
+}
+
// ===========================================================================
\ No newline at end of file
diff --git a/scripts/client/skin-select.js b/scripts/client/skin-select.js
index 6ae824de..2f3149e7 100644
--- a/scripts/client/skin-select.js
+++ b/scripts/client/skin-select.js
@@ -53,7 +53,12 @@ function processSkinSelectKeyPress(keyCode) {
}
logToConsole(LOG_DEBUG, `Switching to skin ${allowedSkins[skinSelectorIndex][1]} (Index: ${skinSelectorIndex}, Skin: ${allowedSkins[skinSelectorIndex][0]})`);
skinSelectMessageTextTop = allowedSkins[skinSelectorIndex][1];
- localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ if(getGame() == VRR_GAME_GTA_IV) {
+ //natives.changePlayerModel(natives.getPlayerId(), allowedSkins[skinSelectorIndex][0]);
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ } else {
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ }
} else if(keyCode == SDLK_PAGEDOWN) {
if(skinSelectorIndex <= 0) {
skinSelectorIndex = allowedSkins.length-1;
@@ -62,7 +67,12 @@ function processSkinSelectKeyPress(keyCode) {
}
logToConsole(LOG_DEBUG, `Switching to skin ${allowedSkins[skinSelectorIndex][1]} (Index: ${skinSelectorIndex}, Skin: ${allowedSkins[skinSelectorIndex][0]})`);
skinSelectMessageTextTop = allowedSkins[skinSelectorIndex][1];
- localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ if(getGame() == VRR_GAME_GTA_IV) {
+ //natives.changePlayerModel(natives.getPlayerId(), allowedSkins[skinSelectorIndex][0]);
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ } else {
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ }
} else if(keyCode == SDLK_RETURN) {
sendNetworkEventToServer("vrr.skinSelected", skinSelectorIndex);
toggleSkinSelect(false);
@@ -109,7 +119,13 @@ function toggleSkinSelect(state) {
game.setCameraLookAt(frontCameraPosition, localPlayer.position, true);
}
- localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ if(getGame() == VRR_GAME_GTA_IV) {
+ //natives.changePlayerModel(natives.getPlayerId(), allowedSkins[skinSelectorIndex][0]);
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ } else {
+ localPlayer.skin = allowedSkins[skinSelectorIndex][0];
+ }
+
skinSelectMessageTextTop = allowedSkins[skinSelectorIndex][1];
setLocalPlayerControlState(false, false);
} else {
diff --git a/scripts/client/sync.js b/scripts/client/sync.js
index 3da59074..7b7d7413 100644
--- a/scripts/client/sync.js
+++ b/scripts/client/sync.js
@@ -116,7 +116,7 @@ function syncVehicleProperties(vehicle) {
}
if(getGame() == VRR_GAME_GTA_SA) {
- let allUpgrades = getGameData().vehicleUpgrades[getGame()];
+ let allUpgrades = getGameConfig().vehicleUpgrades[getGame()];
for(let i in allUpgrades) {
vehicle.removeUpgrade(i);
}
@@ -391,4 +391,20 @@ function syncElementProperties(element) {
}
}
+// ===========================================================================
+
+function receiveBlipFromServer(model, position) {
+ if(getGame() == VRR_GAME_GTA_IV) {
+
+ }
+}
+
+// ===========================================================================
+
+function receivePickupFromServer(model, position) {
+ if(getGame() == VRR_GAME_GTA_IV) {
+
+ }
+}
+
// ===========================================================================
\ No newline at end of file
diff --git a/scripts/client/utilities.js b/scripts/client/utilities.js
index bbf48cb2..a4354ffe 100644
--- a/scripts/client/utilities.js
+++ b/scripts/client/utilities.js
@@ -188,8 +188,10 @@ function setLocalPlayerControlState(controlState, cursorState = false) {
game.SET_PLAYER_CONTROL(localClient.index, boolToInt(controlState));
}
- localPlayer.collisionsEnabled = controlState;
- localPlayer.invincible = true;
+ if(getGame() != VRR_GAME_GTA_IV) {
+ localPlayer.collisionsEnabled = controlState;
+ localPlayer.invincible = true;
+ }
}
// ===========================================================================
@@ -283,26 +285,21 @@ function enterVehicleAsPassenger() {
function giveLocalPlayerWeapon(weaponId, ammo, active) {
logToConsole(LOG_DEBUG, `[VRR.Utilities] Giving weapon ${weaponId} with ${ammo} ammo`);
- localPlayer.giveWeapon(weaponId, ammo, active);
- forceWeaponAmmo = localPlayer.getWeaponAmmunition(getWeaponSlot(weaponId));
- forceWeaponClipAmmo = localPlayer.getWeaponClipAmmunition(getWeaponSlot(weaponId));
forceWeapon = weaponId;
-}
-
-// ===========================================================================
-
-function giveLocalPlayerWeapon(weaponId, ammo, active) {
- logToConsole(LOG_DEBUG, `[VRR.Utilities] Giving weapon ${weaponId} with ${ammo} ammo`);
if(getGame() == VRR_GAME_MAFIA_ONE) {
localPlayer.giveWeapon(weaponId, 0, ammo);
forceWeaponAmmo = 0;
forceWeaponClipAmmo = ammo;
} else {
localPlayer.giveWeapon(weaponId, ammo, active);
- forceWeaponAmmo = localPlayer.getWeaponAmmunition(getWeaponSlot(weaponId));
- forceWeaponClipAmmo = localPlayer.getWeaponClipAmmunition(getWeaponSlot(weaponId));
+ if(getGame() < VRR_GAME_GTA_IV) {
+ forceWeaponAmmo = localPlayer.getWeaponAmmunition(getWeaponSlot(weaponId));
+ forceWeaponClipAmmo = localPlayer.getWeaponClipAmmunition(getWeaponSlot(weaponId));
+ } else {
+ forceWeaponAmmo = ammo;
+ forceWeaponClipAmmo = ammo;
+ }
}
- forceWeapon = weaponId;
}
// ===========================================================================
@@ -351,6 +348,9 @@ function setLocalPlayerInterior(interior) {
if(!isGTAIV()) {
localPlayer.interior = interior;
game.cameraInterior = interior;
+ } else {
+ let interiorId = natives.getInteriorAtCoords(localPlayer.position);
+ natives.activateInterior(interiorId, true);
}
}
@@ -618,11 +618,15 @@ function forceLocalPlayerEquippedWeaponItem() {
if(forceWeapon != 0) {
if(localPlayer.weapon != forceWeapon) {
localPlayer.weapon = forceWeapon;
- localPlayer.setWeaponClipAmmunition(getWeaponSlot(forceWeapon), forceWeaponClipAmmo);
- localPlayer.setWeaponAmmunition(getWeaponSlot(forceWeapon), forceWeaponAmmo);
+ if(getGame() <= VRR_GAME_GTA_IV) {
+ localPlayer.setWeaponClipAmmunition(getWeaponSlot(forceWeapon), forceWeaponClipAmmo);
+ localPlayer.setWeaponAmmunition(getWeaponSlot(forceWeapon), forceWeaponAmmo);
+ }
} else {
- forceWeaponClipAmmo = localPlayer.getWeaponClipAmmunition(getWeaponSlot(forceWeapon));
- forceWeaponAmmo = localPlayer.getWeaponAmmunition(getWeaponSlot(forceWeapon));
+ if(getGame() <= VRR_GAME_GTA_IV) {
+ forceWeaponClipAmmo = localPlayer.getWeaponClipAmmunition(getWeaponSlot(forceWeapon));
+ forceWeaponAmmo = localPlayer.getWeaponAmmunition(getWeaponSlot(forceWeapon));
+ }
}
} else {
if(localPlayer.weapon > 0) {
@@ -835,13 +839,13 @@ function setUpInitialGame() {
natives.setPlayersDropMoneyInNetworkGame(false);
natives.setSyncWeatherAndGameTime(false);
natives.usePlayerColourInsteadOfTeamColour(true);
- natives.setDisplayPlayerNameAndIcon(false);
+ natives.setDisplayPlayerNameAndIcon(natives.getPlayerId(), false);
natives.removeTemporaryRadarBlipsForPickups();
natives.setPickupsFixCars(false);
- natives.displayCash(true);
- natives.displayAmmo(true);
- natives.displayHud(true);
- natives.displayAreaName(true);
+ natives.displayCash(false);
+ natives.displayAmmo(false);
+ natives.displayHud(false);
+ natives.displayAreaName(false);
natives.setPoliceRadarBlips(false);
natives.requestAnims("DANCING");
diff --git a/scripts/server/account.js b/scripts/server/account.js
index 50e4ac24..ff9764c5 100644
--- a/scripts/server/account.js
+++ b/scripts/server/account.js
@@ -106,7 +106,7 @@ function toggleAccountGUICommand(command, params, client) {
if(!isPlayerLoggedIn(client)) {
if(getPlayerData().accountData.databaseId != 0) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginGUI(client);
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the login GUI`);
} else {
@@ -115,7 +115,7 @@ function toggleAccountGUICommand(command, params, client) {
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the login message (GUI disabled)`);
}
} else {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerRegistrationGUI(client);
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the register GUI`);
} else {
@@ -566,13 +566,31 @@ function loginSuccess(client) {
client.administrator = true;
}
+ if(doesServerHaveTesterOnlyEnabled()) {
+ if(!hasBitFlag(getPlayerData(client).accountData.flags.moderation, getModerationFlagValue("IsTester"))) {
+ setTimeout(function() {
+ client.disconnect();
+ }, 3500);
+
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
+ logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the error GUI (not a tester).`);
+ showPlayerErrorGUI(client, getLocaleString(client, "NotATester"), getLocaleString(client, "AccessDenied"));
+ return false;
+ } else {
+ logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the "not a tester" error message (GUI disabled).`);
+ messagePlayerError(client, getLocaleString(client, "NotATester"));
+ return false;
+ }
+ }
+ }
+
if(getPlayerData(client).subAccounts.length == 0) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
- showPlayerPromptGUI(client, `You have no characters. Would you like to make one?`, "No characters");
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
+ showPlayerPromptGUI(client, getLocaleString(client, "NoCharactersGUIMessage"), getLocaleString(client, "NoCharactersGUIWindowTitle"));
getPlayerData(client).promptType = VRR_PROMPT_CREATEFIRSTCHAR;
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the no characters prompt GUI`);
} else {
- messagePlayerAlert(client, `You have no characters. Use /newchar to make one.`);
+ messagePlayerAlert(client, getLocaleString(client, "NoCharactersChatMessage", `{ALTCOLOUR}/newchar{MAINCOLOUR}`));
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the no characters message (GUI disabled)`);
}
} else {
@@ -760,7 +778,7 @@ function checkLogin(client, password) {
if(isPlayerLoggedIn(client)) {
logToConsole(LOG_WARN, `[VRR.Account] ${getPlayerDisplayForConsole(client)} attempted to login but is already logged in`);
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginSuccessGUI(client);
} else {
messagePlayerError(client, "You are already logged in!");
@@ -771,7 +789,7 @@ function checkLogin(client, password) {
if(!isPlayerRegistered(client)) {
logToConsole(LOG_WARN, `[VRR.Account] ${getPlayerDisplayForConsole(client)} attempted to login but is not registered`);
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerRegistrationGUI(client);
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the register GUI`);
} else {
@@ -783,7 +801,7 @@ function checkLogin(client, password) {
if(areParamsEmpty(password)) {
logToConsole(LOG_WARN, `[VRR.Account] ${getPlayerDisplayForConsole(client)} attempted to login but failed (empty password). ${getPlayerData(client).loginAttemptsRemaining} login attempts remaining`);
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginFailedGUI(client, `Invalid password! ${getPlayerData(client).loginAttemptsRemaining} tries remaining.`);
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the login GUI with ${getPlayerData(client).loginAttemptsRemaining} login attempts remaining alert.`);
} else {
@@ -799,7 +817,7 @@ function checkLogin(client, password) {
if(!isAccountPasswordCorrect(getPlayerData(client).accountData, hashAccountPassword(getPlayerName(client), password))) {
logToConsole(LOG_WARN, `[VRR.Account] ${getPlayerDisplayForConsole(client)} attempted to login but failed (wrong password). ${getPlayerData(client).loginAttemptsRemaining} login attempts remaining`);
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginFailedGUI(client, `Invalid password! ${getPlayerData(client).loginAttemptsRemaining} tries remaining.`);
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the login GUI with ${getPlayerData(client).loginAttemptsRemaining} login attempts remaining alert.`);
} else {
@@ -819,7 +837,7 @@ function checkLogin(client, password) {
// return true;
//}
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginSuccessGUI(client);
}
@@ -836,7 +854,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
logToConsole(LOG_DEBUG, `[VRR.Account]: Checking registration for ${getPlayerName(client)}`);
if(isPlayerRegistered(client)) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginGUI(client);
} else {
messagePlayerError(client, getLocaleString(client, "AlreadyRegistered"));
@@ -846,7 +864,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(isPlayerLoggedIn(client)) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerLoginSuccessGUI(client);
} else {
messagePlayerError(client, getLocaleString(client, "AlreadyLoggedIn"));
@@ -856,7 +874,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(areParamsEmpty(password)) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedNoPassword"));
logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} failed to create an account (password is blank)`);
} else {
@@ -866,7 +884,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
return false;
}
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
if(areParamsEmpty(confirmPassword)) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedNoPasswordConfirm"));
logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} failed to create an account (password confirm is blank)`);
@@ -874,7 +892,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
}
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
if(areParamsEmpty(emailAddress)) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedNoEmail"));
logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} failed to create an account (email address is blank)`);
@@ -882,7 +900,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
}
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
if(password != confirmPassword) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedPasswordMismatch"));
logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} failed to create an account (password and confirm don't match)`);
@@ -891,7 +909,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(!doesPasswordMeetRequirements(password)) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
// Work on this later. Function should return true by default anyway for now.
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedNoPasswordWeak"));
logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} failed to create an account (password doesn't meet requirements)`);
@@ -901,7 +919,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
return false
}
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
if(!isValidEmailAddress(emailAddress)) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedInvalidEmail"));
return false
@@ -910,7 +928,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
let accountData = createAccount(getPlayerName(client), password, emailAddress);
if(!accountData) {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
showPlayerRegistrationFailedGUI(client, getLocaleString(client, "RegistrationFailedCreateError"));
} else {
messagePlayerAlert(client, getLocaleString(client, "RegistrationFailedCreateError"));
@@ -926,22 +944,36 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
messagePlayerSuccess(client, getLocaleString(client, "RegistrationSuccess"));
if(checkForSMTPModule() && getEmailConfig().enabled) {
messagePlayerAlert(client, getLocaleString(client, "RegistrationEmailVerifyReminder"));
+ let emailVerificationCode = generateEmailVerificationCode();
+ setAccountEmailVerificationCode(getPlayerData(client).accountData, emailVerificationCode);
+ sendEmailVerificationEmail(client, emailVerificationCode);
+ logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} was sent a registration email verification code`);
}
- messagePlayerAlert(client, getLocaleString(client, "RegistrationCreateCharReminder"));
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
- showPlayerRegistrationSuccessGUI(client);
- showPlayerPromptGUI(client, getLocaleString(client, "NoCharactersMessage"), getLocaleString(client, "NoCharactersWindowTitle"), getLocaleString(client, "Yes"), getLocaleString(client, "No"));
- getPlayerData(client).promptType = VRR_PROMPT_CREATEFIRSTCHAR;
+ if(doesServerHaveTesterOnlyEnabled() && !isPlayerATester(client)) {
+ setTimeout(function() {
+ client.disconnect();
+ }, 5000);
- if(checkForSMTPModule() && getEmailConfig().enabled) {
- let emailVerificationCode = generateEmailVerificationCode();
- setAccountEmailVerificationCode(getPlayerData(client).accountData, emailVerificationCode);
- sendEmailVerificationEmail(client, emailVerificationCode);
- logToConsole(LOG_WARN, `${getPlayerDisplayForConsole(client)} was sent a registration email verification code`);
- }
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
+ logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the error GUI (not a tester).`);
+ showPlayerErrorGUI(client, getLocaleString(client, "NotATester"), getLocaleString(client, "AccessDenied"));
+ return false;
+ } else {
+ logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the "not a tester" error message (GUI disabled).`);
+ messagePlayerError(client, getLocaleString(client, "NotATester"));
+ return false;
+ }
} else {
- messagePlayerAlert(client, getLocaleString(client, "NoCharactersChatMessage"));
+ messagePlayerAlert(client, getLocaleString(client, "RegistrationCreateCharReminder"));
+
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
+ showPlayerRegistrationSuccessGUI(client);
+ showPlayerPromptGUI(client, getLocaleString(client, "NoCharactersMessage"), getLocaleString(client, "NoCharactersWindowTitle"), getLocaleString(client, "Yes"), getLocaleString(client, "No"));
+ getPlayerData(client).promptType = VRR_PROMPT_CREATEFIRSTCHAR;
+ } else {
+ messagePlayerAlert(client, getLocaleString(client, "NoCharactersChatMessage"), `{ALTCOLOUR}/newchar{MAINCOLOUR}`);
+ }
}
};
@@ -1084,6 +1116,12 @@ function initClient(client) {
return false;
}
+ if(client.getData("vrr.isInitialized") != null || client.getData("vrr.isInitialized") == true) {
+ return false;
+ }
+
+ client.setData("vrr.isInitialized", true, false);
+
sendPlayerGUIColours(client);
sendPlayerGUIInit(client);
updatePlayerSnowState(client);
@@ -1109,7 +1147,7 @@ function initClient(client) {
messagePlayerAlert(client, getLocaleString(client, "AutoLoggedInIP"));
loginSuccess(client);
} else {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the login GUI.`);
showPlayerLoginGUI(client);
} else {
@@ -1119,7 +1157,7 @@ function initClient(client) {
playRadioStreamForPlayer(client, getServerIntroMusicURL(), true, getPlayerStreamingRadioVolume(client));
}
} else {
- if(getServerConfig().useGUI && doesPlayerHaveGUIEnabled(client)) {
+ if(doesServerHaveGUIEnabled() && doesPlayerHaveGUIEnabled(client)) {
logToConsole(LOG_DEBUG, `[VRR.Account] ${getPlayerDisplayForConsole(client)} is being shown the register GUI.`);
showPlayerRegistrationGUI(client);
} else {
@@ -1453,4 +1491,10 @@ function checkPlayerTwoFactorAuthentication(client, authCode) {
return false;
}
+// ===========================================================================
+
+function isPlayerATester(client) {
+
+}
+
// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/animation.js b/scripts/server/animation.js
index ff253583..4c18f00f 100644
--- a/scripts/server/animation.js
+++ b/scripts/server/animation.js
@@ -70,7 +70,7 @@ function stopPlayerAnimationCommand(command, params, client) {
// ===========================================================================
function showAnimationListCommand(command, params, client) {
- let animList = getGameData().animations[getServerGame()].map(function(x) { return x[0]; });
+ let animList = getGameConfig().animations[getServerGame()].map(function(x) { return x[0]; });
let chunkedList = splitArrayIntoChunks(animList, 10);
@@ -88,7 +88,7 @@ function showAnimationListCommand(command, params, client) {
* @return {Array} The animation's data (array)
*/
function getAnimationData(animationSlot, gameId = getServerGame()) {
- return getGameData().animations[gameId][animationSlot];
+ return getGameConfig().animations[gameId][animationSlot];
}
// ===========================================================================
@@ -145,13 +145,13 @@ function makePlayerStopAnimation(client) {
function getAnimationFromParams(params) {
if(isNaN(params)) {
- for(let i in getGameData().animations[getServerGame()]) {
- if(toLowerCase(getGameData().animations[getServerGame()][i][0]).indexOf(toLowerCase(params)) != -1) {
+ for(let i in getGameConfig().animations[getServerGame()]) {
+ if(toLowerCase(getGameConfig().animations[getServerGame()][i][0]).indexOf(toLowerCase(params)) != -1) {
return i;
}
}
} else {
- if(typeof getGameData().animations[getServerGame()][params] != "undefined") {
+ if(typeof getGameConfig().animations[getServerGame()][params] != "undefined") {
return toInteger(params);
}
}
diff --git a/scripts/server/bitflag.js b/scripts/server/bitflag.js
index 50bbcc22..b095c2e8 100644
--- a/scripts/server/bitflag.js
+++ b/scripts/server/bitflag.js
@@ -62,7 +62,8 @@ let serverBitFlagKeys = {
"TwoFactorAuthVerified",
"NonRoleplayCharacterName",
"CanHearEverything",
- "DontSyncClientElements"
+ "DontSyncClientElements",
+ "IsTester"
],
factionFlagKeys: [
"None",
@@ -409,7 +410,7 @@ function getModerationFlagValue(flagName) {
// ===========================================================================
-function getServerSettingFlagValue(flagName) {
+function getServerSettingsFlagValue(flagName) {
if(flagName == "All") {
return -1;
}
diff --git a/scripts/server/business.js b/scripts/server/business.js
index e68a0722..24af8bfa 100644
--- a/scripts/server/business.js
+++ b/scripts/server/business.js
@@ -1336,6 +1336,10 @@ function createAllBusinessBlips() {
// ===========================================================================
function createBusinessEntrancePickup(businessId) {
+ if(!areServerElementsSupported()) {
+ return false;
+ }
+
if(!getServerConfig().createBusinessPickups) {
return false;
}
@@ -1348,18 +1352,24 @@ function createBusinessEntrancePickup(businessId) {
}
logToConsole(LOG_VERBOSE, `[VRR.Job]: Creating entrance pickup for business ${getBusinessData(businessId).name} (model ${pickupModelId})`);
-
- getBusinessData(businessId).entrancePickup = createGamePickup(pickupModelId, getBusinessData(businessId).entrancePosition, getGameConfig().pickupTypes[getServerGame()].business);
- setElementOnAllDimensions(getBusinessData(businessId).entrancePickup, false);
- setElementDimension(getBusinessData(businessId).entrancePickup, getBusinessData(businessId).entranceDimension);
- updateBusinessPickupLabelData(businessId);
- addToWorld(getBusinessData(businessId).entrancePickup);
+
+ if(areServerElementsSupported()) {
+ getBusinessData(businessId).entrancePickup = createGamePickup(pickupModelId, getBusinessData(businessId).entrancePosition, getGameConfig().pickupTypes[getServerGame()].business);
+ setElementOnAllDimensions(getBusinessData(businessId).entrancePickup, false);
+ setElementDimension(getBusinessData(businessId).entrancePickup, getBusinessData(businessId).entranceDimension);
+ updateBusinessPickupLabelData(businessId);
+ addToWorld(getBusinessData(businessId).entrancePickup);
+ }
}
}
// ===========================================================================
function createBusinessEntranceBlip(businessId) {
+ if(!areServerElementsSupported()) {
+ return false;
+ }
+
if(!getServerConfig().createBusinessBlips) {
return false;
}
@@ -1372,11 +1382,13 @@ function createBusinessEntranceBlip(businessId) {
}
logToConsole(LOG_VERBOSE, `[VRR.Job]: Creating entrance blip for business ${getBusinessData(businessId).name} (model ${blipModelId})`);
-
- getBusinessData(businessId).entranceBlip = createGameBlip(getBusinessData(businessId).entrancePosition, blipModelId, 1, getColourByName("businessBlue"));
- setElementOnAllDimensions(getBusinessData(businessId).entranceBlip, false);
- setElementDimension(getBusinessData(businessId).entranceBlip, getBusinessData(businessId).entranceDimension);
- addToWorld(getBusinessData(businessId).entranceBlip);
+
+ if(areServerElementsSupported()) {
+ getBusinessData(businessId).entranceBlip = createGameBlip(getBusinessData(businessId).entrancePosition, blipModelId, 1, getColourByName("businessBlue"));
+ setElementOnAllDimensions(getBusinessData(businessId).entranceBlip, false);
+ setElementDimension(getBusinessData(businessId).entranceBlip, getBusinessData(businessId).entranceDimension);
+ addToWorld(getBusinessData(businessId).entranceBlip);
+ }
}
}
@@ -1396,12 +1408,14 @@ function createBusinessExitPickup(businessId) {
}
logToConsole(LOG_VERBOSE, `[VRR.Job]: Creating exit pickup for business ${getBusinessData(businessId).name} (model ${pickupModelId})`);
-
- getBusinessData(businessId).exitPickup = createGamePickup(pickupModelId, getBusinessData(businessId).exitPosition, getGameConfig().pickupTypes[getServerGame()].business);
- setElementDimension(getBusinessData(businessId).exitPickup, getBusinessData(businessId).exitDimension);
- setElementOnAllDimensions(getBusinessData(businessId).exitPickup, false);
- updateBusinessPickupLabelData(businessId);
- addToWorld(getBusinessData(businessId).exitPickup);
+
+ if(areServerElementsSupported()) {
+ getBusinessData(businessId).exitPickup = createGamePickup(pickupModelId, getBusinessData(businessId).exitPosition, getGameConfig().pickupTypes[getServerGame()].business);
+ setElementDimension(getBusinessData(businessId).exitPickup, getBusinessData(businessId).exitDimension);
+ setElementOnAllDimensions(getBusinessData(businessId).exitPickup, false);
+ updateBusinessPickupLabelData(businessId);
+ addToWorld(getBusinessData(businessId).exitPickup);
+ }
}
}
}
@@ -1421,15 +1435,17 @@ function createBusinessExitBlip(businessId) {
blipModelId = getBusinessData(businessId).exitBlipModel;
}
- logToConsole(LOG_VERBOSE, `[VRR.Job]: Creating exit blip for business ${getBusinessData(businessId).name} (model ${blipModelId})`);
+ if(areServerElementsSupported()) {
+ logToConsole(LOG_VERBOSE, `[VRR.Job]: Creating exit blip for business ${getBusinessData(businessId).name} (model ${blipModelId})`);
- getBusinessData(businessId).exitBlip = createGameBlip(getBusinessData(businessId).exitPosition, blipModelId, 1, getColourByName("businessBlue"));
- setElementDimension(getBusinessData(businessId).exitBlip, getBusinessData(businessId).entranceDimension);
- setElementOnAllDimensions(getBusinessData(businessId).exitBlip, false);
- //getBusinessData(businessId).exitBlip.interior = getBusinessData(businessId).exitInterior;
- //setEntityData(getBusinessData(businessId).exitBlip, "vrr.owner.type", VRR_BLIP_BUSINESS_EXIT, false);
- //setEntityData(getBusinessData(businessId).exitBlip, "vrr.owner.id", businessId, false);
- addToWorld(getBusinessData(businessId).exitBlip);
+ getBusinessData(businessId).exitBlip = createGameBlip(getBusinessData(businessId).exitPosition, blipModelId, 1, getColourByName("businessBlue"));
+ setElementDimension(getBusinessData(businessId).exitBlip, getBusinessData(businessId).entranceDimension);
+ setElementOnAllDimensions(getBusinessData(businessId).exitBlip, false);
+ //getBusinessData(businessId).exitBlip.interior = getBusinessData(businessId).exitInterior;
+ //setEntityData(getBusinessData(businessId).exitBlip, "vrr.owner.type", VRR_BLIP_BUSINESS_EXIT, false);
+ //setEntityData(getBusinessData(businessId).exitBlip, "vrr.owner.id", businessId, false);
+ addToWorld(getBusinessData(businessId).exitBlip);
+ }
}
}
}
@@ -1907,6 +1923,10 @@ function getBusinessIdFromDatabaseId(databaseId) {
// ===========================================================================
function updateBusinessPickupLabelData(businessId) {
+ if(!areServerElementsSupported()) {
+ return false;
+ }
+
if(getBusinessData(businessId).exitPickup != null) {
setEntityData(getBusinessData(businessId).exitPickup, "vrr.owner.type", VRR_PICKUP_BUSINESS_EXIT, false);
setEntityData(getBusinessData(businessId).exitPickup, "vrr.owner.id", businessId, false);
diff --git a/scripts/server/class.js b/scripts/server/class.js
index 61038308..6219c2d1 100644
--- a/scripts/server/class.js
+++ b/scripts/server/class.js
@@ -22,8 +22,6 @@ function initClassScript() {
class ServerData {
constructor(dbAssoc = false) {
this.databaseId = 0;
- this.name = "";
- this.password = "";
this.needsSaved = false;
this.newCharacter = {
@@ -59,6 +57,8 @@ class ServerData {
this.guiTextColourSecondary = [0, 0, 0];
this.showLogo = true;
this.inflationMultiplier = 1;
+ this.testerOnly = false;
+ this.settings = 0;
this.antiCheat = {
enabled: false,
@@ -104,52 +104,47 @@ class ServerData {
bank: dbAssoc["svr_newchar_bank"],
skin: dbAssoc["svr_newchar_skin"],
},
+ this.settings = toInteger(dbAssoc["svr_settings"]);
+
this.connectCameraPosition = toVector3(dbAssoc["svr_connectcam_pos_x"], dbAssoc["svr_connectcam_pos_y"], dbAssoc["svr_connectcam_pos_z"]);
this.connectCameraLookAt = toVector3(dbAssoc["svr_connectcam_lookat_x"], dbAssoc["svr_connectcam_lookat_y"], dbAssoc["svr_connectcam_lookat_z"]);
- //this.characterSelectCameraPosition = toVector3(dbAssoc["svr_charselect_cam_pos_x"], dbAssoc["svr_charselect_cam_pos_y"], dbAssoc["svr_charselect_cam_pos_z"]);
- //this.characterSelectCameraLookAt = toVector3(dbAssoc["svr_charselect_cam_lookat_x"], dbAssoc["svr_charselect_cam_lookat_y"], dbAssoc["svr_charselect_cam_lookat_z"]);
-
- //this.characterSelectPedPosition = toVector3(dbAssoc["svr_charselect_ped_pos_x"], dbAssoc["svr_charselect_ped_pos_y"], dbAssoc["svr_charselect_ped_pos_z"]);
- //this.characterSelectPedHeading = toFloat(dbAssoc["svr_charselect_ped_rot_z"]);
- //this.characterSelectInterior = toInteger(dbAssoc["svr_charselect_int"]);
- //this.characterSelectDimension = toInteger(dbAssoc["svr_charselect_int"]);
-
this.hour = toInteger(dbAssoc["svr_start_time_hour"]);
this.minute = toInteger(dbAssoc["svr_start_time_min"]);
this.minuteDuration = toInteger(dbAssoc["svr_time_min_duration"]);
this.weather = toInteger(dbAssoc["svr_start_weather"]);
- this.fallingSnow = intToBool(dbAssoc["svr_start_snow_falling"]);
- this.groundSnow = intToBool(dbAssoc["svr_start_snow_ground"]);
- this.useGUI = intToBool(dbAssoc["svr_gui"]);
+ this.fallingSnow = hasBitFlag(this.settings, getServerSettingsFlagValue("FallingSnow"));
+ this.groundSnow = hasBitFlag(this.settings, getServerSettingsFlagValue("GroundSnow"));
+ this.useGUI = hasBitFlag(this.settings, getServerSettingsFlagValue("GUI"));
this.guiColourPrimary = [toInteger(dbAssoc["svr_gui_col1_r"]), toInteger(dbAssoc["svr_gui_col1_g"]), toInteger(dbAssoc["svr_gui_col1_b"])];
this.guiColourSecondary = [toInteger(dbAssoc["svr_gui_col2_r"]), toInteger(dbAssoc["svr_gui_col2_g"]), toInteger(dbAssoc["svr_gui_col2_b"])];
this.guiTextColourPrimary = [toInteger(dbAssoc["svr_gui_textcol1_r"]), toInteger(dbAssoc["svr_gui_textcol1_g"]), toInteger(dbAssoc["svr_gui_textcol1_b"])];
//this.guiTextColourSecondary = [toInteger(dbAssoc["svr_gui_textcol2_r"]), toInteger(dbAssoc["svr_gui_textcol2_g"]), toInteger(dbAssoc["svr_gui_textcol2_b"])];
- this.showLogo = intToBool(dbAssoc["svr_logo"]);
+ this.showLogo = hasBitFlag(this.settings, getServerSettingsFlagValue("Logo"));
this.inflationMultiplier = toFloat(dbAssoc["svr_inflation_multiplier"]);
+ this.testerOnly = hasBitFlag(this.settings, getServerSettingsFlagValue("Testing"));
this.antiCheat = {
- enabled: intToBool(dbAssoc["svr_ac_enabled"]),
- checkGameScripts: intToBool(dbAssoc["svr_ac_check_scripts"]),
- gameScriptBlackListEnabled: intToBool(dbAssoc["svr_ac_script_bl"]),
- gameScriptWhiteListEnabled: intToBool(dbAssoc["svr_ac_script_wl"]),
+ enabled: hasBitFlag(this.settings, getServerSettingsFlagValue("Anticheat")),
+ checkGameScripts: hasBitFlag(this.settings, getServerSettingsFlagValue("CheckGameScripts")),
+ gameScriptBlackListEnabled: hasBitFlag(this.settings, getServerSettingsFlagValue("GameScriptBlackList")),
+ gameScriptWhiteListEnabled: hasBitFlag(this.settings, getServerSettingsFlagValue("GameScriptWhiteList")),
gameScriptWhiteList: [],
gameScriptBlackList: [],
};
this.discordBotToken = intToBool(dbAssoc["svr_discord_bot_token"]);
- this.discordEnabled = intToBool(dbAssoc["svr_discord_bot_enabled"]);
+ this.discordEnabled = hasBitFlag(this.settings, getServerSettingsFlagValue("DiscordBot"));
- this.createJobPickups = intToBool(dbAssoc["svr_job_pickups"]);
- this.createBusinessPickups = intToBool(dbAssoc["svr_biz_pickups"]);
- this.createHousePickups = intToBool(dbAssoc["svr_house_pickups"]);
- this.createJobBlips = intToBool(dbAssoc["svr_job_blips"]);
- this.createBusinessBlips = intToBool(dbAssoc["svr_biz_blips"]);
- this.createHouseBlips = intToBool(dbAssoc["svr_house_blips"]);
+ this.createJobPickups = hasBitFlag(this.settings, getServerSettingsFlagValue("JobPickups"));
+ this.createBusinessPickups = hasBitFlag(this.settings, getServerSettingsFlagValue("BusinessPickups"));
+ this.createHousePickups = hasBitFlag(this.settings, getServerSettingsFlagValue("HousePickups"));
+ this.createJobBlips = hasBitFlag(this.settings, getServerSettingsFlagValue("JobBlips"));
+ this.createBusinessBlips = hasBitFlag(this.settings, getServerSettingsFlagValue("BusinessBlips"));
+ this.createHouseBlips = hasBitFlag(this.settings, getServerSettingsFlagValue("HouseBlips"));
this.introMusicURL = dbAssoc["svr_intro_music"];
- this.useRealTime = intToBool(dbAssoc["svr_time_realtime_enabled"]);
+ this.useRealTime = hasBitFlag(this.settings, getServerSettingsFlagValue("RealTime"));
this.realTimeZone = dbAssoc["svr_time_realtime_timezone"];
this.discordConfig = {
diff --git a/scripts/server/client.js b/scripts/server/client.js
index 0ab56b6f..c0ea074c 100644
--- a/scripts/server/client.js
+++ b/scripts/server/client.js
@@ -410,14 +410,14 @@ function showPlayerPromptGUI(client, promptMessage, promptTitle, yesButtonText,
// ===========================================================================
-function showPlayerInfoGUI(client, infoMessage, infoTitle) {
+function showPlayerInfoGUI(client, infoMessage, infoTitle, buttonText = "OK") {
logToConsole(LOG_DEBUG, `[VRR.Client] Sending show info GUI signal to ${getPlayerDisplayForConsole(client)} (Title: ${infoTitle}, Message: ${infoMessage})`);
sendNetworkEventToPlayer("vrr.showInfo", client, infoMessage, infoTitle, buttonText);
}
// ===========================================================================
-function showPlayerErrorGUI(client, errorMessage, errorTitle) {
+function showPlayerErrorGUI(client, errorMessage, errorTitle, buttonText = "OK") {
logToConsole(LOG_DEBUG, `[VRR.Client] Sending show error GUI signal to ${getPlayerDisplayForConsole(client)} (Title: ${errorTitle}, Message: ${errorMessage})`);
sendNetworkEventToPlayer("vrr.showInfo", client, errorMessage, errorTitle, buttonText);
}
@@ -522,13 +522,6 @@ function sendPlayerFrozenState(client, state) {
// ===========================================================================
-function givePlayerWeapon(client, weaponId, ammo, active = true) {
- logToConsole(LOG_DEBUG, `[VRR.Client] Sending signal to ${getPlayerDisplayForConsole(client)} to give weapon (Weapon: ${weaponId}, Ammo: ${ammo})`);
- sendNetworkEventToPlayer("vrr.giveWeapon", client, weaponId, ammo, active);
-}
-
-// ===========================================================================
-
function clearPlayerWeapons(client) {
logToConsole(LOG_DEBUG, `[VRR.Client] Sending signal to ${getPlayerDisplayForConsole(client)} to clear weapons`);
sendNetworkEventToPlayer("vrr.clearWeapons", client);
@@ -1141,4 +1134,16 @@ function setPlayerInfiniteRun(client, state) {
sendNetworkEventToPlayer("vrr.infiniteRun", client, state);
}
+// ==========================================================================
+
+function sendBusinessEntranceToPlayer(client, businessId, name, entrancePosition, blipModel, pickupModel, hasInterior, hasItems) {
+ sendNetworkEventToPlayer("vrr.business", client, businessId, name, entrancePosition, blipModel, pickupModel, hasInterior, hasItems);
+}
+
+// ==========================================================================
+
+function sendHouseEntranceToPlayer(client, houseId, entrancePosition, blipModel, pickupModel, hasInterior) {
+ sendNetworkEventToPlayer("vrr.house", client, houseId, entrancePosition, blipModel, pickupModel, hasInterior);
+}
+
// ==========================================================================
\ No newline at end of file
diff --git a/scripts/server/command.js b/scripts/server/command.js
index 58984a11..a7d1aaa6 100644
--- a/scripts/server/command.js
+++ b/scripts/server/command.js
@@ -68,12 +68,12 @@ function loadCommands() {
commandData("stopanim", stopPlayerAnimationCommand, "", getStaffFlagValue("None"), true, true, "Stops your current animation"),
],
antiCheat: [
- commandData("addacscriptwl", addAntiCheatWhiteListedScriptCommand, "