Search the Community

Showing results for tags 'javascript'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • RAGE Multiplayer
    • Announcements
    • Discussion
    • Suggestions
  • Scripting
    • Scripting
    • Resources
  • Community
    • Support
    • Servers
    • Media Gallery
  • Non-English
    • Русский - Russian
    • Français - French
    • Deutsch - German
    • Espanol - Spanish
    • Română - Romanian
    • Portuguesa - Portuguese
    • Polski - Polish

Categories

  • Scripts
  • Gamemodes
  • Libraries
  • Plugins
  • Maps
  • Tools

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Facebook


Youtube


Skype


Web


VK

Found 28 results

  1. unkaid

    [JS] Regional Restrictions

    Version 1.0.0

    15 downloads

    Simple solution to check incoming connections from unwanted countries. I. Install geoip-Lite: npm i geoip-lite II. Edit country_ban list with the specified country codes https://dev.maxmind.com/geoip/legacy/codes/iso3166/ III. Save and put this script to "server-files\packages" and add require('./countryBan'); in index.js
  2. unkaid

    Realtime Weather

    Version 1.0.0

    53 downloads

    Server-sided script, that getting a real weather hourly and sets it in the gta 5 world. HowTo: I. Install getJSON: npm install get-json --save II. Go to https://developer.accuweather.com/ and register as the Developer. III. To get your new API key, create your WeatherAPP here, https://developer.accuweather.com/user/me/apps On the question: "What programming language is your APP written in?" Answer will be: JavaScript. IV. Go to https://www.accuweather.com/ and find your preferred location on the map or by the search field, for example: Moscow, Russia. To set more accurate location to your preferred, click on the nearest point on the map, for me it is Yakimanka, then click on 'Hourly". V. The URL will look like this: https://www.accuweather.com/en/ru/yakimanka/2515350/hourly-weather-forecast/2515350 Well, 2515350 is the Location Key that we will use further. VI. Let's assemble your AccuWeather URL: http://dataservice.accuweather.com/forecasts/v1/hourly/1hour/YOUR_LOCATION_KEY?apikey=YOUR_API_KEY VII. Paste new AccuWeather URL into the script and save it. Warning! The Trial Version of AccuWeather is limited for 50 requests per day. GitHub
  3. This occurs due to player stamina hitting zero, resulting in hp being lost. Below is the workaround for this in both C# and JavaScript. C# //Subscribe the Tick event Events.Tick += Tick; public void Tick(List<Events.TickNametagData> nametags) { RAGE.Game.Player.RestorePlayerStamina(1.0F); } JavaScript mp.events.add('render', () => { mp.game.player.restoreStamina(100); });
  4. I'm thinking which language should I use to make a server. Which is more supported for RageMP? Which would u recommend to start and why? I have learned both so the knowledge wouldn't be a problem.
  5. SnakeWiz

    [JS] Basic Clothes Menu

    Version 1.0.0

    329 downloads

    Simple cloth menu, you can open it by pressing F2. This script requires NativeUI library, download it from the resources tab. It's my first resource, do not expect too much. https://github.com/Snakewiz/ClothesMenu
  6. BySarG

    Js Resource

    Hi everyone! I have a custom.js on my server-files/bridge/resources/custom folder. My meta.xml look like this: <meta> <info name="custom" type="script" /> <script src="custom.js" /> </meta> My custom.js: console.log("works"); But i cant see the console.log in my console after exectue the file server.exe. My console returns: [N] Starting network... - OK: (IPv4-only) at 127.0.0.1:22005 (node:12532) ExperimentalWarning: The ESM module loader is experimental. [M] Announcing into master server... Loading packages Initializing bridge (0.3.7.0).. This is not a published, standalone application and we are unable to locate the .NET Core SDK. Please make sure that it is installed; see http://microsoft.com/net/core for more details. Initializing Bootstrapper.dll (0.3.7.0).. -> SERVER STARTED AT 17/01/2019 15:03:56 ACLEnabled: True Loaded 451 entries from vehicleData.json Loading resources.. -> Starting custom resource.. custom: loading scripts.. found 1 script(s) -> Resource custom started! -> Starting admin resource.. admin: loading scripts.. found 1 script(s) [M] Connected to master list. admin: compiling scripts.. admin: instantiating Main.AdminScript.. admin: loading server events.. found 2 server event(s) admin: loaded 2 server events(s) admin: loading commands.. found 9 command(s) admin: loaded 9 commands(s) -> Resource admin started! -> Starting welcomemessages resource.. welcomemessages: loading scripts.. found 1 script(s) welcomemessages: compiling scripts.. welcomemessages: instantiating WelcomeMessages.. welcomemessages: loading server events.. found 2 server event(s) welcomemessages: loaded 2 server events(s) -> Resource welcomemessages started! Started! Waiting for connections.. [P] Plugin bridge.dll loaded! Started HTTP server at 22006 port. Any ideas? Thanks!
  7. Hi everyone! In need of a custom script for a Custom NameTag, I found the @hartority script, however, it was an outdated project and it had been made for version 0.2 of RageMP, with some references already removed, well, I bring you today the corrected code. Requirements: RageMP server files. Nothing more! Just have fun. Introduction: This script is a reliable edition of the one produced by @hartority with only a few references to the RageMP library, so all code is credit @hartority. Let's start: 1. Go to "client_packages" folder in "RAGEMP/server-files" directory, usually: 2. Create a JavaScript archive (.js) named "customtag.js", example: 3. Inside the "customtag.js" paste this code: 4. Save "customtag.js" file, and open "index.js" in "C:\RAGEMP\server-files\client_packages" directory and put this: End! Just test it and tell me if something goes wrong Usage example: The original code topic of @hartority: Thanks for all feedbacks, mad thanks @hartority for your commitment if you do not authorize this topic, please let me know
  8. Can you guys add the HAS_PED_BEEN_DAMAGED_BY_WEAPON native as a javascript function like those in Client-side functions? For some reason calling this native (hash 0x2D343D2219CD027A) using mp.game.invoke seems to not work at all. It was supposed to return true/false but instead it just returns the second parameter passed to the invoke() function.
  9. Ребят, хелпаните пожалуйста. Нужно создать таблицу id|Nickname|Убийства|Смерти. Как создать событие, которое бы передавало значение в поле ''Убийства''/''Смерти''? Возможно ли упорядочить игроков в таблице по кол-ву убийств? К примеру, на первом месте игрок с самым большем кол-вом убийств, а на последнем с самым маленьким. Как передать значения ''Убийства''/''Смерти'' в MySQL базу данных? HTML таблицы: <!-- Online players --> <div id="online_players" style="display: none;"> <h1>Online players</h1> <table id="online_players_table"> <thead> <tr> <th class="id">ID</th> <th class="name">Name</th> <th class="kills" id="kills">Kills</th> <th class="death" id="death">death</th> </tr> </thead> <tbody> </tbody> </table> </div> javascript таблицы: let centered = false; // Show players online. document.addEventListener('keydown', function(e) { if ((e.key === 'z' || e.keyCode === 90) && !chatActive) { if (!centered) { $('#online_players').css('top', Math.max(0, (($(window).height() - $('#online_players').outerHeight()) / 2) + $(window).scrollTop()) + 'px'); $('#online_players').css('left', Math.max(0, (($(window).width() - $('#online_players').outerWidth()) / 2) + $(window).scrollLeft()) + 'px'); centered = true; } $('#online_players').css('display', 'block'); } }); function addPlayerInTheTable(id, name, kill, death) { let text = ` <tr id="player-${id}"> <td class="id">${id}</td> <td class="name">${name}</td> <td class="kill" id="kill">fh</td> <td class="death">${death}</td> </tr>`; $("#kill").text(`fedffdxvb`); // (${kills}).text(`1`); let formated = text.replace(/\n/g, '').replace(/"/g, '"'); $('#online_players #online_players_table tbody').append(text);
  10. Hi, here is a simple SQL auth system. Made with UI from @MarkCavalli ! Connection by email / password.. Nothing much to say You can use it if you are beginner or not. Here is github: https://github.com/Protocole63/RageMPAuthSystem Cya PS: if you want to go further in a RP script, see MarkCavalli GM:
  11. Проблема такова, когда игрок садится на скутер, вызывается окно аренды (|Арендовать | Отмена|), после нажатия на кнопку ''Арендовать'' у него должно списаться 100$, но проблема в том, что после того как он садится на этот же скутер еще раз, сумма снятия становится на 100$ больше. То есть 1-й раз снимает 100$, 2-й раз снимает 200$, 3-й раз снимает 300$ и т.д. Как сделать, так чтобы снималась конкретно установленная сумма (100$), и чтобы после нажатия на кнопку ''Арендовать'' при повторной посадке на арендованный скутер окно аренды не вызывалось? HTML окна аренды: <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="css/style.css" type="text/css"/> <title>Title</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script type="text/javascript" src="js/arenda.js"> </script> </head> <body> <div class="container" id="container"> <form> <h3>Аренда данного транспорта стоит 100$</h3> <input type="button" class="testbutton" id="rent" onclick= "mp.trigger('playerClickRent');" value="Арендовать"/> <input type="button" class="testbutton" id="otmena" name="otmena" onclick = "$('.container').hide()" value="Отмена"/> </form> </div> <script> $("#rent").click(function() { $('#container').fadeOut("slow", function() { }); }); </script> </body> </html> JavaScript, который принимает событие клика по кнопке ''Арендовать'' на Client-Side: function playerEnterVehicleHandler(vehicle, seat) { const vehicleID = vehicle.id; if (vehicleID == 9){ mp.browsers.new('package://freeroam/arenda/arenda.html'); mp.gui.cursor.visible = true; mp.events.add("playerClickRent", () => { mp.events.callRemote("rent");//отправляет данные на сервер }); }; }; mp.events.add("playerEnterVehicle", playerEnterVehicleHandler); JavaScript, который принимает событие клика по кнопке "Арендовать" на Server-Side: mp.events.add('rent', (player) => { console.log(`нажал кнопку Арендовать`); player.outputChatBox(`${player.name}"арендовал скутер"`); if (player.data.customMoney >= 100){ player.data.customMoney -= 100;} else { player.removeFromVehicle() player.outputChatBox("Недостаточно средств")}; });
  12. Проблема такова, когда игрок садится на скутер, вызывается окно аренды (|Арендовать | Отмена|), после нажатия на кнопку ''Арендовать'' у него должно списаться 100$, но проблема в том, что после того как он садится на этот же скутер еще раз, сумма снятия становится на 100$ больше. То есть 1-й раз снимает 100$, 2-й раз снимает 200$, 3-й раз снимает 300$ и т.д. Как сделать, так чтобы снималась конкретно установленная сумма (100$), и чтобы после нажатия на кнопку ''Арендовать'' при повторной посадке на арендованный скутер окно аренды не вызывалось? HTML окна аренды: <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="css/style.css" type="text/css"/> <title>Title</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script type="text/javascript" src="js/arenda.js"> </script> </head> <body> <div class="container" id="container"> <form> <h3>Аренда данного транспорта стоит 100$</h3> <input type="button" class="testbutton" id="rent" onclick= "mp.trigger('playerClickRent');" value="Арендовать"/> <input type="button" class="testbutton" id="otmena" name="otmena" onclick = "$('.container').hide()" value="Отмена"/> </form> </div> <script> $("#rent").click(function() { $('#container').fadeOut("slow", function() { }); }); </script> </body> </html> JavaScript, который принимает событие клика по кнопке ''Арендовать'' на Client-Side: function playerEnterVehicleHandler(vehicle, seat) { const vehicleID = vehicle.id; if (vehicleID == 9){ mp.browsers.new('package://freeroam/arenda/arenda.html'); mp.gui.cursor.visible = true; mp.events.add("playerClickRent", () => { mp.events.callRemote("rent");//отправляет данные на сервер }); }; }; mp.events.add("playerEnterVehicle", playerEnterVehicleHandler); JavaScript, который принимает событие клика по кнопке "Арендовать" на Server-Side: mp.events.add('rent', (player) => { console.log(`нажал кнопку Арендовать`); player.outputChatBox(`${player.name}"арендовал скутер"`); if (player.data.customMoney >= 100){ player.data.customMoney -= 100;} else { player.removeFromVehicle() player.outputChatBox("Недостаточно средств")}; });
  13. Нужно ввести команду от лица игрока автоматически, во время какого-то ивента. К примеру -Когда игрок вводит команду /arrest 228, чтобы сразу же после этой команды вводилась команда /me надел наручники на преступника. -Или к примеру при нажатии в nativeui на кнопку ''Арендовать'' вводилась автоматически команда /arenda. Можно ли это как-то реализовать? просто инфы на Вики и форуме не нашел.
  14. Зашел на вики и увидел что для JavaScript есть только функции и евенты на Server-side. А для C# есть и для Server-side, и для Client-side. То есть, я правильно понял, что на JS можно написать ТОЛЬКО Server-side, а на C# можно и клиентскую сторону и серверную? И могу ли я совмещать C# и JS?
  15. Hello, I have one suggestion for team RageMP, please create extension for Microsoft Visual Studio Code. When I write scripts, I have to look at api constantly. Please, consider my suggestion
  16. Один из способов работы с UI клиента, с помощью CEF(HTML), на примере модального окна со списком игроков(ник, ip, ping) Дабы не использовать хостинг, развернем веб-сервер прямо в игровом сервере. Начнём. Создаем в каталоге 'packages/keker' папку 'ui' (в ней будут лежать клиентские файлы) и файл 'web.js', и объявляем его в 'packages/keker/index.js' добавив туда строку: require('./web'); В 'web.js' вставляем этот код: const http = require('http'); const fs = require('fs'); const path = require('path'); const url = require('url'); const mimeType = { // mime типы по расширениям файлов '.ico': 'image/x-icon', '.html': 'text/html', '.js': 'text/javascript', '.json': 'application/json', '.css': 'text/css', '.png': 'image/png', '.jpg': 'image/jpeg', '.wav': 'audio/wav', '.mp3': 'audio/mpeg', '.svg': 'image/svg+xml', '.pdf': 'application/pdf', '.doc': 'application/msword', '.eot': 'appliaction/vnd.ms-fontobject', '.ttf': 'aplication/font-sfnt' }; http.createServer(function (req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); // разрешаем кросс-деменые запросы let parsedUrl = url.parse(req.url); // отсекаем от url все лишнее let filePath = __dirname+'/ui' + parsedUrl.pathname; // Парсим url в путь к файлу let ext = path.extname(filePath); // получаем расширение файла if(req.url=="/api/players_list.json"){ // отдельная ссылка для генерации JSON списка игроков let pl = { online: mp.players.length, slots: mp.players.size, players: [] } mp.players.forEach(player => { pl.players.push({ name: player.name, ip: player.ip, ping: player.ping }); }); res.writeHead(200, { 'Content-Type': mimeType['.json'] }); res.end(JSON.stringify(pl), 'utf-8'); } else { fs.readFile(filePath, function(error, content) { if (error) { if(error.code == 'ENOENT'){ // если файл отсутсвует res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('404 Not Found'); } else { // другие ошибки res.writeHead(500); res.end('Error: '+error.code+' ..\n'); } } else { res.writeHead(200, { 'Content-Type': mimeType[ext] || 'text/plain' }); res.end(content, 'utf-8'); } }); } }).listen(8080); // вешаем наш веб сервер на свободный порт, у меня это 8080 Он создает веб-сервер для выдачи статики из нашей папки 'ui'. В папку 'ui' добавляем наш HTML и CSS и JS файлы, HTML и CSS комментировать не буду, тут у всех на свой вкус players_list.html: <div class="p-list"> <p>Игроков онлайн: 0/100</p> <table id="pl-table" border="0" cellpadding="5"> <tr> <th>Имя:</th> <th>IP:</th> <th>Ping:</th> </tr> <tr><td>Nick</td><td>0.0.0.0</td><td>0</td></tr> </table> </div> main.css: .p-list { cursor: none; position: absolute; top: 20%; left: 20%; width: 60%; height: 60%; background: rgba(96,125,139,0.8); text-align: center; align-content: center; color: #eee; font-size: 18px; overflow-y: scroll; border: 1px solid #eee; border-radius: 5px; display: none; } .p-list p { padding: 8px 0px; } .p-list table { width: 100%; color: #eee; } .p-list tr { text-align: center; } .p-list td { border-top: 1px solid #eee; width: 30%; } ::-webkit-scrollbar { width: 12px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); border-radius: 10px; } ::-webkit-scrollbar-thumb { background: #37474F; border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); } Туда же добавим и JS файл который будет отвечать за функционал. JQuery у нас уже подключен, его можно спокойно использовать. main.js: const addr = "http://127.0.0.1:8080/"; // Здесь обязательно задаем адресс вашего сервера и порт на котором висит веб var pl_enable = false; // флаг проверки открыто/скрыто окно со списком игроков var css_el = document.createElement("link"); // создаем элемент подключающий css css_el.rel = "stylesheet"; css_el.href = addr+"main.css"; $("head").append(css_el);// подключаем его в head $.get( addr+"players_list.html", function( data ) { // загружаем HTML нашего модального окна $("body").append( data ); // вставляем его в body }); $("body").keydown(function( e ) { // событие нажания на кнопку if(e.which == 9){ // 9 KeyCode кнопки TAB if(pl_enable){ // если модальное окно открыто скрываем его pl_enable = false; $('.p-list').hide(); } else { pl_enable = true; $.getJSON( addr+"api/players_list.json", function( data ) { // получаем список игроков $(".p-list p").html("<b>Игроков онлайн: "+data.online+"/"+data.slots+"</b>"); // кол-во онлайна let str = "<tr><th>Ник:</th><th>IP:</th><th>Ping:</th></tr>"; for(let i = 0; i < data.players.length; i++){ str += "<tr><td>"+data.players[i].name+"</td><td>"+data.players[i].ip+"</td><td>"+data.players[i].ping+"</td>"; } $("#pl-table").html(str); // запихиваем список в модальное окно }); $('.p-list').show(); // делаем его видимым } mp.invoke("focus", pl_enable); // отключаем игровой процесс делаем видимым курсор (он лагучий и находится под меню) //курсор можно накатать свой но нам это пока не надо } }); Теперь нужно отослать наш скрипт на исполнение игроку, я это сделал в 'common.js' на событие о подключении игрока: player.outputChatBox("<script src='http://127.0.0.1:8080/main.js'></script>"); // указываем ваш адрес сервера и веб порт /*кавычки только так, снаружи двойные внутри одинарные, по другому не сработало, если у вас обьем кода больше не забывайте экранировать кавычки */ Ну вот и все, теперь при нажатии на TAB в игре, должно открыться модальное окно со списком игроков. Так же в папку 'ui' можно полностью перенести стандартное меню и изменять уже его, переход на него будет выполнятся так: player.outputChatBox("<script>document.location.href = 'http://127.0.0.1:8080/index.html';</script>"); // не забываем подставить свой адрес и порт Так же в клиентских скриптах можно использовать этот метод для отправки команд на сервер: mp.invoke("command", "команда агрумент1 агрумент2 ..."); Веб-сервер выдает большинство mime типов так что можно подключать всякие фреймворки типа Bootstrap, Angular, React и прочие плюшки.
  17. Hello guys, I am trying to make a function that returns if a player is located around a marker/position at a certain radius. The first solution in my mind was to set an interval in which it checks every 5 sec or so if the player is inside the radius of a position. But if I put the json/object inside the setInterval function, the server crashes when this function is called. I know for sure the json is the problem, beacuse if i just put a console.log inside the setInterval, it works fine. Error: async hook stack has become corrupted (actual: 10, expected: 11) There's other code going on than just this piece, I thought this might be enough to see what's going. Many thanks in advance for your help. Have a great day! Erwin let positions = require('./positions.json'); function startCheckingCaps(player){ setInterval(function(){ positions.cap.forEach(function(v,i){ if (inRadius(v)){ //inRadius checks if player.position is inside the radius of the current position 'v' player.notify("capturing " + v.name); } else { player.notify("not capturing"); } }); //console.log("if its just this in setInterval, it works just fine."); }, 5000); } mp.events.add('playerJoin', (player) => { startCheckingCaps(player); //<------------------------- this is the one from above });
  18. Всем привет. Зашел я значить на вики, да бы посмотреть что и как, какой функционал допилили, описание немного почитать. Наткнулся на серверною и клиентскою часть ивентов и охренел. Хочу спросить у вас дорогие форумчане - почему так мало ивентов, будут ли допиливать новые, что слышали по этому поводу?. С описанием функций и примерами тоже проблемы, но это вопрос времени. И помимо этого хочу задать такой вопрос. (возможно он не много глупый) Я так понимаю что серверною часть можно писать на разных языках. И если это так то поправочка к первому вопросу, меня интересуют ивенты на nodejs.
  19. Всем доброго времени суток! Я уже неоднократно упоминал на сервере дискорда о такой штуке, как ESLint. Кто-то относится скептически, кто-то поддерживает, а кто-то и вовсе пропускает мимо. Сегодня постараемся разобраться что это за монстр, да и нужен ли он вообще? Теория Для чего это все? На самом деле все очень просто! ESLint поможет привести ваш код к общему стилю. "Что в этом такого? Я и сам могу писать весь свой код в едином стиле" ответите вы, но не все так просто. Каждому человеку свойственно ошибаться или проявлять невнимательность, особенно после долгой работы над кодом. ESLint крайне необходим при работе в команде. Зачем? Да опять же, все очень просто! Кто-то привык ставить в конце точку с запятой, кто-то нет, кто-то максимум пишет 80 символов в строку, кто-то 120, а кто-то громоздит вообще сколько душе угодно. В конечно итоге - ваш код или код вашей команды может превратиться в сплошную кашу, а вам это нужно? Если вы и дальше считаете, что вам это нужно - просто закройте статью. Практика Теперь когда вы знаете, что такое ESLint и зачем он нужен - давайте начнем его использовать? Для того, чтобы это сделать - не нужно каких-то особых усилий, достаточно установить пакет используя пакетный менеджер npm. npm install eslint --save-dev Установили, отлично, что теперь? Теперь нам нужно создать файл в котором мы будем прописывать наши правила о "правильном коде". Для этого достаточно создать в директории файл .eslintrc.js (так же возможно варианты просто .eslitrc и .eslintrc.json, читайте подробнее на официальном сайте). После создания файла - нам нужно сконфигурировать наш конфиг, я приведу простой пример. Е сли вам нужно что-то особенное или заточенное под что-то конкретное - вы можете без проблем найти необходимую документацию все на том же официальном сайте. .eslintrc.js: module.exports = { // Среды - среды, в которых ваши .js файлы будут запущены. Каждая среда предоставляет определенный набор предопределенных глобальных переменных. 'env': { 'node': true, 'es6': true }, 'extends': 'eslint:recommended', // Здесь таятся наши правила. 'rules': { // Каждое правило принимает тип оповещения о себе (2 или error, 1 или warn, 0 или off(не оповещать)) и непосрественно сами аргументы для правида. // Правило обеспечивает согласованный стиль отступов. В данном примере 4 пробела. 'indent': [2, 4], // оповещать как ошибку // Правило обеспечивает последовательное использование точек с запятой. 'semi': [2, 'always'], // оповещать как ошибку // Правило обеспечивает согласованный стиль привязки для блоков. 'brace-style': [2, '1tbs'], // оповещать как ошибку // Правило направлено на устранение неиспользуемых переменных, функций и параметров функций. 'no-unused-vars': [1], // оповещать как предупреждение // Разрешим вывод в консоль (используйте это правило только при разработке). 'no-console': [0] } }; Полный список всех правил вы можете найти здесь. Окей, установили, настроили, что дальше? Дальше нам необходимо проверить все наши .js файлы на наличие ошибок или предупреждений. Ниже я приведу пример простого .js файла, чтобы нагляднее было видно где есть ошибки, а где их нет. Для того, чтобы проверить файлы необходимо просто запустить команду: node ./node_modules/eslint/bin/eslint test.js Где test.js - имя вашего файла, соответственно. Пример файла: function Foo() { console.log('Foo') } function Fooo() { console.log('Fooo'); } Запустив ESLint вы должны увидеть что-то вроде этого: 1:10 warning 'Foo' is defined but never used no-unused-vars 2:1 error Opening curly brace does not appear on the same line as controlling statement brace-style 3:1 error Expected indentation of 4 spaces but found 2 indent 3:21 error Missing semicolon semi 6:10 warning 'Fooo' is defined but never used no-unused-vars Все справедливо и все по делу. Я не буду разбирать каждую ошибку, но если вы пройдетесь по коду в соответствии с нашими правилами, то вы увидите, что ESLint говорит нам справедливые вещи. И это все? Нет, это не все. Я думаю многие из вас согласятся, что такой вариант проверки неудобен, т.к. он требует постоянного запуска команды из окна терминала (консоли), что не очень-то и удобно. А есть выход? Да, конечно выход есть! На сегодняшний день многие современные текстовые редакторы обеспечивают проверку вашего кода, используя ваши правила ESLint. Visual Studio Code: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint Atom: https://github.com/AtomLinter/linter-eslint Notepad++ https://sourceforge.net/projects/notepad-linter/ Я не буду писать полный список, т.к. вы сможете сами без проблем найти поддержку ESLint для вашего редактора в гугле. Заключение После прочтения данной статьи у вас сформировались базовые понятия о том, что такое ESLint и зачем это нужно. Я надеюсь, что для кого-то из вас эта статья была полезна и, возможно, все таки убедит вас в том, что его использования крайне важно. Спасибо за внимание! Я надеюсь, что вы не напрасно потратили свое время.
  20. Всем доброго времени суток, в данной статье я хотел бы немного рассказать о Yarn. Если вы знаете, что это такое и используете, либо твердо решили для себя, что не будете использовать Yarn, то можете просто закрыть данную статью. Предусловие Yarn - это пакетный менеджер, разработанный компанией Facebook, на стадии его разработки так же подключились Google, Exponent и Tilde. Почему стоит использовать Yarn? Файл yarn.lock В файле package.json, с помощью которого Yarn и npm отслеживают зависимости, номера версий не указываются точно, вместо этого задается их диапазон. Таким образом, вы можете задать определенную основную или вспомогательную версию, при этом позволяя npm установить последний патч с исправлениями каких-либо багов. В идеальном мире семантического версионирования, релизы с патчами не содержат коренных изменений. Но, к сожалению, в реальности это не всегда верно. Стратегия, выбранная npm может привести к тому, что на двух машинах с идентичными файлами package.json будут установлены различные версии пакетов, что может привести к появлению багов. Чтобы избежать несоответствия версий, установленная версия закрепляется в файле блокировки. При каждом добавлении модуля создается файл yarn.lock. Таким образом вы можете гарантировать, что на другой машине будет установлен тот же самый пакет; при этом у нас сохраняется диапазон допустимых версий в файле package.json. В npm команда npm shrinkwrap так же генерирует файл блокировки, а команда npm install считывает его до чтения package.json, также как Yarn сначала читает yarn.lock. Разница состоит в том, что Yarn всегда автоматически обновляет yarn.lock, а в npm это надо делать вручную. Параллельная установка Независимо от того, устанавливается ли пакет с помощью npm или Yarn, при этом решается серия задач. В npm эти задачи выполняются последовательно и отдельно для каждого пакета, это значит, что пока пакет не установлен полностью, следующий пакет будет ждать. В Yarn эти операции выполняются параллельно, что улучшает производительность. Для сравнения я установил пакет express с помощью npm и Yarn, не используя кэш, файлы shrinkwrap или lock; всего в установке 42 файла. npm: 9 секунд Yarn: 1.37 секунд Я не поверил своим глазам. Повторение дало такие же результаты. Затем я установил gulp со 195 зависимостями. npm: 11 секунд Yarn: 7.81 секунд Кажется, что разница зависит от количества устанавливаемых пакетов, в любом случае Yarn быстрее. Yarn или npm: различия в интерфейсе командной строки Кроме функциональных отличий, в Yarn также отличаются команды. Некоторые команды npm удалены, некоторые модифицированы, а пара интересных команд добавлена. yarn global В отличие от npm, где глобальные операции выполняются за счет опции -g или --global, команды Yarn нуждаются в префиксе global. Также как и в npm, специфические для проекта зависимости глобально не устанавливаются. Префикс global работает только с командами yarn add, yarn bin, yarn ls и yarn remove. За исключением yarn add, все эти команды идентичны своим эквивалентам в npm. Документация global. yarn install Команда npm install устанавливает все зависимости из файла package.json и позволяет вам добавлять новые пакеты. Команда yarn install только устанавливает зависимости, перечисленные в файле yarn.lock или package.json, именно в таком порядке. Документация yarn install Документация npm install yarn add [–dev] Аналогично npm install <package>, команда yarn add <package> добавляет пакет и устанавливает зависимости. Как видно из названия команды, она добавляет зависимости, это означает автоматическое сохранение ссылки на пакет в файле package.json, также как это делается в npm с флагом --save. Флаг --dev в Yarn добавляет зависимости для разработки, также как флаг --save-dev в npm. Документация yarn add Документация npm install yarn licenses [ls|generate-disclaimer] На момент написания в npm нет эквивалента этой команды. Yarn licenses lsвыводит список лицензий всех установленных в проекте пакетов, а yarn licenses generate-disclaimer генерирует дисклеймер, содержащий текст всех лицензий всех пакетов в проекте. Некоторые лицензии требуют включать текст лицензии в ваш проект, поэтому этот инструмент весьма полезен. Документация yarn licenses yarn why Эта команда смотрит в граф зависимостей и выясняет, почему указанный пакет установлен в вашем проекте. Возможно, вы сами добавили его, а, может, это зависимость установленного вами пакета. Команда yarn why помогает вам с этим разобраться. Документация yarn why yarn upgrade Эта команда обновляет пакеты до последней версии, соответствующей диапазону из package.json вместо установки точных версий из yarn.lock. Чтобы добиться того же в npm, вам надо последовательно выполнить: rm -rf node_modules npm install Эту команду не надо путать с npm update, обновляющей пакеты до самой свежей версии. Документация yarn upgrade yarn generate-lock-entry Команда yarn generate-lock-entry генерирует файл yarn.lock на основе зависимостей из package.json. Это похоже на npm shrinkwrap. Эту команду следует использовать с осторожностью, так как файл блокировки генерируется и обновляется автоматически при добавлении и обновлении зависимостей с помощью yarn add и yarn upgrade. Документация yarn generate-lock-entry Документация npm shrinkwrap Стабильность и надежность А что, если шумиха вокруг Yarn преждевременна? В первый же день релиза появилось много сообщений о проблемах, но темпы решения проблем поражают. Это показывает серьезную работу по обнаружению и исправлению багов. Если смотреть на количество и типы проблем, Yarn кажется стабильным для большинства пользователей, но он может не подойти для каких-то отдельных случаев. Учтите, что несмотря на то, что пакетный менеджер может быть очень важен для вашего проекта, это всего лишь пакетный менеджер. Если возникают проблемы, то переустановка пакетов не должна быть сложной, также как и возврат к npm. Перспективы Возможно, вы опасаетесь повторения истории с Node.js и io.js. Напомню, что io.js был форком Node.js, созданным несколькими основными разработчиками после разногласий по поводу управления проектом. Меньше, чем через год, обе команды пришли к соглашению, io.js был слит с Node.js и прекращен. Независимо от того, кто был прав, это обогатило Node.js новыми функциями. Я вижу схожие паттерны между npm и Yarn. Хотя Yarn это не форк, он исправляет некоторые из недостатков npm. Разве будет плохо, если npm учтет это и попросит Facebook, Google и остальных разработчиков Yarn улучшить npm? Хотя об этом слишком рано пока говорить, но я надеюсь, что так и произойдет. В любом случае, будущее Yarn выглядит светлым. Сообщество проявляет интерес к появлению нового пакетного менеджера. К сожалению, пока отсутствует дорожная карта проекта, поэтому я не знаю, какие сюрпризы Yarn готовит для нас. Заключение По умолчанию Yarn набирает больше очков, чем npm. У нас есть файл блокировки, установка пакетов быстра, как никогда и они все автоматически сохраняются в package.json. Последствия установки и использования Yarn минимальны — вы можете попробовать его только в одном проекте, чтобы увидеть, подходит он вам или нет. Это делает Yarn превосходной заменой npm. Я мог бы однозначно рекомендовать попробовать Yarn в каком-нибудь проекте, раньше или позже. Если вы осторожны в установке и использовании новых программ, подождите пару месяцев. В конце концов, npm проверен в боевых условиях, а в мире разработки программного обеспечения это немаловажно. Если же вы замечали, что вам приходиться ждать окончания установки пакетов npm, то вам самое время ознакомиться с руководством по переходу на Yarn. Пару слов от себя Yarn устанавливает пакеты гораздо быстрее, чем npm. Если в вашем проекте более одного разработчика, то используя Yarn вы может быть уверенны в том, что у всех разработчиков будут установлены пакеты одинаковых версий, что исключит возможность некорректной работы кода из-за версии пакета. Официальный сайт: https://yarnpkg.com/ Источники: https://habrahabr.ru, http://prgssr.ru
  21. N1kS

    Урок №1 - Основы

    Данная статья является первой часть курса уроков по JavaScript. В ней будут рассмотрены основные моменты языка JavaScript. В данной статье мы познакомимся с основными элементами языка JavaScript, к ним относятся: Базовые типы: строки, числа, логические переменные. Операторы. Массивы. Функции. Регулярные выражения. Циклы. 1. Базовые типы let variableName; // объявление новой перемнной с именем 'variableName' let str = ‘Hello world!!’; // строка let a = 1; // целое число let b = 1.3; // дробное число let boolTrue = true; // истина let bollFalse = false; // ложь const myConst = 5; // объявление const задаёт константу, то есть переменную, которую нельзя менять myConst = 10; // ошибка, константу имзенить нельзя 2. Операторы 2.1. Арифметические К арифметическим оператором относятся: + (сложение) - (вычитаение) * (умножение) / (деление) % (остаток от деления) let a = 1; let b = 2; let c = a + b; // 3 let d = c * 2; // 6 let e = d / 3; // 2 let f = e % 2; // 0 let g = 1.5; let h = 2.3; let i = g + h; // 3.8 i++; // 4.8 i--; // 3.8 let str1 = "Hello"; let str2 = "World!"; let str3 = str1 + " " + str2; // "Hello World!" 2.2. Логические && (и) || (или) if (5 > 3 && 5 < 6 ) { // условие верно, т.к. 5 больше 3 и 5 меньше 6 } if (5 > 3 && 5 < 4) { // условие не верно, т.к 5 больше 3, но 5 не меньше 4 } if (5 > 3 || 5 < 4) { // условие верно, т.к 5 больше 3 или 5 меньше 4 } if (5 < 3 || 5 > 10) { // условие не верно, т.к 5 больше 3 и 5 меньше 10 } 2.3. Сравнение == (равно без приведения типов) === (равно с приведением типов) != (не равно без приведения типов) !== (не равно с приведением типов) < (меньше) > (больше) <= (меньше или равно) >= (больше или равно) 1 == 1; // true 1 == '1'; // true 1 === 1; // true 1 === '1'; // false, т.к. типы не совпадают 1 != 2; // true 1 != 1; // false 1 > 1; // false 1 >= 1; // true 2 > 1; // true 2 >= 1; // true 3 < 4; // true 3 < 3; // false 3 <= 3; // true 0 == false; // true 0 === false; // false, т.к. типы не совпадают 3. Массивы В JavaScript индексация массива начинается с 0, то есть первый элемент в массиве имеет индекс 0, второй 1 и т.д. 3.1 Создание и изменение массива let arr = []; // создание пустого массива let arr = [1, 2, 3, 'Bob', 4, 5, 678.95]; // создание массива с элементами arr[0]; // 1 arr[2]; // 3 arr[3]; // "Bob"; arr[6]; // 678.95 arr[3] = "RAGE"; arr[3]; // "RAGE" arr[2] = 176; arr[2]; // 176 3.2 Авто-длина length У каждого массива есть свойство length, которое автоматом меняется при каждом обновлении массива. Длина массива - это не количество элементов, а максимальный целый ключ + 1: a = []; a[0] = 1; a[1000] = 1; a.length; // в массиве всего 2 элемента, но результат будет равен 1001, т.к. максимальный целый ключ - 1000 3.3 Перебор элементов let a = [1, 2, 3, 4] for (let i = 0; i < a.length; i++) { console.log(a[i]); // выведет каждое значение массива } a.forEach(function(item, index, arr) { // item - значение, index - номер(индекс), arr - массив, который переберается console.log(item); // альтернативный вариант перебора массива. }); 3.4 Добавление и удаление элементов в массив let arr = [3, 5, 7, 9]; arr.push(11); // добавит в конец массива число 11 arr.pop(); // удалит с конца массива последний элемент arr.pop(); // удалит с конца массива последний элемент console.log(arr); // выведет все значения массива, в данном случае [3, 5, 7] arr.unshift(1); // добавит в начало массива число 1 console.log(arr); // выведет все значения массива, в данном случае [1, 3, 5, 7] arr.shift(); // удалит с начала массива первый элемент console.log(arr); // выведет все значения массива, в данном случае [3, 5, 7] Об остальных методах для работы с массива вы можете прочитать здесь. 4. Функции 4.1 Создание функция function имя(параметры) { // какой-то код } function summ(a, b) { return a + b; // функция вернет результат суммы числа a и b } let c = summ(1, 5); // 6 4.2 Функции - объекты В JavaScript функции являются полноценными объектами встроенного класса Function. Именно поэтому их можно присваивать переменным, передавать и, конечно, у них есть свойства: function f() { } f.test = 6 console.log(f.test) // 6 4.3 Параметры функции Функции можно запускать с любым числом параметров. Если функции передано меньше параметров, чем есть в определении, то отсутствующие считаются undefined. function division(a, b = 2) { return a / b; } let a = division(10, 5); // вернет 2, т.к. мы передали оба параметру в функцию let b = division(10); // вернет 5, т.к. мы передали только один параметр в функцию, а b = 2, если он не передан 4.4 Работа с неопределенным числом параметров function sayHi() { for (var i = 0; i < arguments.length; i++) { console.log("Привет, " + arguments[i]); } } sayHi("Винни", "Пятачок"); // 'Привет, Винни', 'Привет, Пятачок' Частая ошибка новичков – попытка применить методы Array к arguments. Это невозможно: function sayHi() { var a = arguments.shift(); // ошибка! нет такого метода! } sayHi(1); Дело в том, что arguments – это не массив Array. В действительности, это обычный объект, просто ключи числовые и есть length. На этом сходство заканчивается. Никаких особых методов у него нет, и методы массивов он тоже не поддерживает. Впрочем, никто не мешает сделать обычный массив из arguments, например так: function Foo() { var args = []; for (var i = 0; i < arguments.length; i++) { args[i] = arguments[i]; } console.log(args); // [1, 2, 3, 4]; } Foo(1, 2, 3, 4); 5. Регулярные выражения Регулярные выражения в javascript имеют особую краткую форму и стандартный PCRE-синтаксис. Работают они через специальный объект RegExp. Кроме того, у строк есть свои методы search,match,replace, но чтобы их понять - разберем-таки сначала RegExp. В дальнейшем на эту тему будет написан отдельный урок, в котором все будет объяснено более подробно. Объект типа RegExp, или, короче, регулярное выражение, можно создать двумя путями /pattern/флаги new RegExp("pattern"[, флаги]) pattern - регулярное выражение для поиска (о замене - позже), а флаги - строка из любой комбинации символов g(глобальный поиск), i(регистр неважен) и m(многострочный поиск). Первый способ используется часто, второй - иногда. Например, два таких вызова эквивалентны: var reg = /ab+c/i var reg = new RegExp("ab+c", "i") При втором вызове - т.к регулярное выражение в кавычках, то нужно дублировать \ // эквивалентны re = new RegExp("\\w+") re = /\w+/ При поиске можно использовать большинство возможностей современного PCRE-синтаксиса. 6. Циклы 6.1 Цикл while с предоусловием let i = 0; while (i < 10) { // цикл будет увеличивать значение перемнной i на 10 до тех пор, пока проверка i < 10 не вернет false i++; } 6.2 Цикл while с пост условием Цикл, описанный, таким образом, сначала выполняет тело, а затем проверяет условие. let i = 0; do { i++; } while (i < 10); Таким образом, цикл выполненный в разделе 6.1, после окончания итераций присвоит переменной i значение 10, а цикл выполненный в разделе 6.2, после окончания итерация присвоит переменной i значение 11. 6.3 Цикл for Чаще всего применяется цикл for. Выглядит он так: for (начало; условие; шаг) { // тело цикла } Пример цикла, который выведет значение для i от 0 до 10 включительно: for (let i = 0; i <= 10; i++) { console.log(i); } В данном цикле: Начало: i = 0. Условие: i <= 10. Шаг: i++. Тело цикла: console.log(i), т.е. код внутри фигурных скобок (они не обязательны, если только одна операция) 6.4 Прерывание цикла break Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива break. Например, следующий цикл остановиться если значение переменной i будет больше 50. for (let i = 0; i <= 100; i++) { if (i > 50) { break; } } Директива continue прекращает выполнение текущей итерации цикла. Она – в некотором роде «младшая сестра» директивы break: прерывает не весь цикл, а только текущее выполнение его тела, как будто оно закончилось. Её используют, если понятно, что на текущем повторе цикла делать больше нечего. Например, следующий цикл использует continue, чтобы не выводить нечетные числа: for (let i = 0; i <= 10; i++) { if (i % 2 != 0) { continue; } console.log(i); // выведет число, если оно четное. }
  22. Хотел бы помочь всем новичкам и посоветовать им, как начать учить JavaScript. Лучшими в рунете по изучению JS являются: Официальная документация от Mozila Developer Network - https://developer.mozilla.org/ru/docs/Web/JavaScript , Книга Ильи Кантора - Современный учебник по JavaScript https://learn.javascript.ru . Node JS: Документаций по Ноде значительно меньше, из годных я бы отметил видеокурс Ильи Кантора - https://learn.javascript.ru/screencast/nodejs . Надеюсь я кому-то помог. Удачи в скриптинге
  23. Ano

    How 2 JavaScript

    Hello people, I'v just started learning JavaScript with SoloLearn. Two years ago i started to get into c++ with this cours. I think with this webside or by using their app you can learn JavaScript and other languages easily. They can teach you JavaScript, C++, Python, Java, PHP, HTML, Swift, CSS and some others, as well. You have to read what they show you and then they will ask you something about what you did read. After giving the right answer you'll get into the next step. If you have problems, you can get help or talk with other users. Start: https://www.sololearn.com/ JavaScript: https://www.sololearn.com/Play/JavaScript Courses: https://www.sololearn.com/Courses/
  24. Пример создания зон, территорий, и событий когда игрок входит/покидает их. Зоны будут 2х типов 2D и 3D, различия между ними в том что 3D зона имеет высоту равную ее радиусу, то есть если игрок находится выше или ниже радиуса зоны то он в ней не находится, 2D же зоны не имеют высоты и игрок находясь на любом уровне на/под ними все равно находится внутри. Создаем в каталоге 'packages/keker' файл 'zones.js', объявим его в 'packages/keker/index.js' добавив туда строку: require("./zones"); Добавляем в 'zones.js' этот код: mp.Vector3.Distance = function (v1, v2){ return (Math.sqrt(Math.pow((v2.x - v1.x),2) + Math.pow((v2.y - v1.y),2)+ Math.pow((v2.z - v1.z),2))); } mp.Vector3.Distance2D = function (v1, v2){ return (Math.sqrt(Math.pow((v2.x - v1.x),2) + Math.pow((v2.y - v1.y),2))); } var Zone = class Zone { constructor(n ,v, r, t){ this.name = n; // Название зоны this.center = v; // Центральная точка this.radius = r; // Радиус this.type = t; // Тип 2D или 3D this.insidePlayers = []; // Массив игроков находящихся в зоне this.interval = InitInterval(this); } BroadcastMessage(s){ // Фунция рассылки сообщения игрокам находящимся в нутри этой зоны this.insidePlayers.forEach(player => { player.outputChatBox(s); }); } } function InitInterval(zone){ return setInterval(function(){ mp.players.forEach(player => { let dist = (zone.type=="2D") ? mp.Vector3.Distance2D(player.position, zone.center) : mp.Vector3.Distance(player.position, zone.center); if(dist < zone.radius && zone.insidePlayers.indexOf(player) < 0){ zone.insidePlayers.push(player); mp.events.call("playerEnterZone", zone, player); } else if (dist > zone.radius && zone.insidePlayers.indexOf(player) >= 0){ zone.insidePlayers.splice(zone.insidePlayers.indexOf(player), 1); mp.events.call("playerExitZone", zone, player); } }) }, 500); } var Zones = class Zones { constructor(){ this._Zone = Zone; this.zones = []; } Add(n, v, r, t){ if(this.zones[n]) this.Remove(n); let z = new this._Zone(n, v, r, t); this.zones[n] = z; return z; } AddZone3D(n, v, r){ return this.Add(n, v, r, '3D'); } AddZone2D(n, v, r){ return this.Add(n, v, r, '2D'); } Remove(n){ let z = this.zones[n]; clearInterval(z.interval); delete this.zones[n]; } Get(n){ return this.zones[n]; } } mp.Zones = new Zones(); mp.events.add({"playerQuit" : (player, reason, kickReason) => { for(let key in mp.Zones.zones) { // Удаление игрока из зоны при выходе let zone = mp.Zones.zones[key]; if (zone.insidePlayers.indexOf(player) >= 0){ zone.insidePlayers.splice(zone.insidePlayers.indexOf(player), 1); } } } }); Теперь в любом удобном месте, или в 'events/common.js' добавляем события для зон: mp.events.add({ "playerEnterZone": (zone, player) => { /* Событие когда игрок вошел в зону на входе получаем zone - обьект зоны, и игрока - player */ }, "playerExitZone": (zone, player) => { /* Событие когда игрок покинул зону на входе получаем zone - обьект зоны, и игрока - player */ } }); Методы и свойства для работы с зонами: let zone = mp.Zones.AddZone3D("zone1", new mp.Vector3(10, 25, 46), 10); // Создает 3D зону с названием zone1, в точке X:10;Y:25;Z:46; и радиусом 10 let zone = mp.Zones.AddZone2D("zone1", new mp.Vector3(10, 25, 46), 10); // Создает 2D зону с названием zone1, в точке X:10;Y:25;Z:46; и радиусом 10 let zone = mp.Zones.Get('zone1'); // Получает зону с названием zone1 mp.Zones.Remove('zone1'); // Удаляет зону zone1 zone.BroadcastMessage("Сообщение"); // Рассылает игрокам находящимся в зоне чат сообщение; zone.insidePlayers // Массив с игроками находящимися в зоне zone.name // Название зоны Прошу строго не судить так как это костыльный метод, пока данный функционал не добавят в API.
  25. После создании структуры персонажа не удается вызвать функцию из структуры Существует данный скрипт global.PLAYERS = {}; function AddPlayer(playerid, skin, name, health, armor, eat, money, bank, weapons, arrests, stars, drugs, fraction, rank) { PLAYERS[playerid] = {}; const temp = {}; temp.name = name; temp.skin = skin; temp.health = health; temp.armor = armor; temp.eat = eat; temp.money = money; temp.bank = bank; temp.weapons = weapons; temp.arrests = arrests; temp.stars = stars; temp.fraction = fraction; temp.rank = rank; temp.drugs = drugs; this.GetName=function(){ return this.name; } this.GetSkin=function(){ return this.skin; } this.SetSkin=function(skin){ this.skin = skin; } this.GetHp=function(){ return this.health; } this.SetHp=function(health){ this.health = health; } this.GetHp=function(){ return this.health; } this.SetHp=function(health){ this.health = health; } this.GetArm=function(){ return this.armor; } this.SetArm=function(armor){ this.armor = armor; } this.GetEat=function(){ return this.eat; } this.SetEat=function(eat){ this.eat = eat; } this.GetMoney=function(){ return this.money; } this.SetMoney=function(money){ this.money = money; } this.GetBank=function(){ return this.bank; } this.SetBank=function(bank){ this.bank = bank; } this.GetDrugs=function(){ return this.drugs; } this.SetDrugs=function(drugs){ this.drugs = drugs; } this.GetWeapons=function(){ return this.weapons; } this.SetBank=function(weapons){ this.weapons = weapons; } this.AddWeapon=function(weapon){ this.weapons.push(weapon);} this.RemoveWeapon=function(weapon){ this.weapons.remove(this.indexOf(weapon));} this.GetArrests=function(){ return this.arrests; } this.AddArrests=function(){ this.arrests += 1; } this.GetStars=function(){ return this.stars; } this.SetStars=function(stars){ this.stars = stars; } this.GetFraction=function(){ return this.fraction; } this.SetFraction=function(fraction){ this.fraction = fraction; } this.GetRank=function(){ return this.rank; } this.SetRank=function(rank){ this.rank = rank; } PLAYERS[playerid] = temp; } function RemovePlayer(playerid) { PLAYERS[playerid] = {}; } При подключении игрока вызывается эвент "playerJoin" а в нем функция : AddPlayer(player.id, models["a_f_y_hipster_02"], player.name, 100, 100, 100, 500, 0, {"Pistol": 900}, 0, 0, 0, 0, 0); В мод добавлена команда: "getdata": (player, args) => { let id = player.id; player.outputChatBox('Name:<br /><b>'+PLAYERS[id].name+'</b>'); player.outputChatBox('skin:<br /><b>'+PLAYERS[id].skin+'</b>'); player.outputChatBox('health:<br /><b>'+PLAYERS[id].health+'</b>'); player.outputChatBox('armor:<br /><b>'+PLAYERS[id].armor+'</b>'); player.outputChatBox('eat:<br /><b>'+PLAYERS[id].eat+'</b>'); player.outputChatBox('money:<br /><b>'+PLAYERS[id].money+'</b>'); player.outputChatBox('bank:<br /><b>'+PLAYERS[id].bank+'</b>'); }, При вызове команды выходит ошибка, PLAYERS[0].name is not defined где именно я накосячил с ООП структурой? (P.S переходил с Lua )