Jump to content

Recommended Posts

Система "оффлайн" ларьков

 

pkodev-shop.png

 

Одним из игровых аспектов игры является торговля между персонажами посредством особых ларьков (лавок), которые могут открывать игроки изучив специальное умение. Игрок выставляет свои предметы за определенную цену, а остальные игроки могут покупать их.

 

Однако, для такой торговли игрок должен находиться в игре, то есть быть подключенным к серверу, что вынуждает его оставлять свой компьютер постоянно включенным и держать игровой клиент свернутым. Это очень неудобно, поэтому была придумана система "оффлайн" ларьков, которая позволяет игрокам отключаться от сервера и при этом оставаться торговать в ларьках.

 

Возможно несколько способов реализации такой системы, но наиболее распространена система "оффлайн" ларьков через прокси-сервер:

1) Игровой клиент (Game.exe) подключается к прокси-серверу;

2) Прокси-сервер, в свою очередь, открывает соединение с GateServer.exe;

3) Далее, прокси-сервер передает все пакеты между Game.exe и GateServer.exe, при этом анализируя их;

4) Когда игрок открывает торговый ларек, прокси-сервер фиксирует это (GateServer.exe отправил Game.exe пакет успешного открытия ларька);

5) Если игрок отключается от сервера будучи в торговом ларьке, то прокси-сервер закрывает соединение с Game.exe, но при этом сохраняет соединение с GateServer.exe и начинает имитировать Game.exe. Таким образом, GateServer.exe не подозревает о факте отключения Game.exe и персонаж игрока остается торговать в ларьке на сервере.

Game.exe |
Game.exe | <---------> pkodev.stallserver.exe <---------> GateServer.exe
Game.exe |

 

В данной теме обсуждается разработка такого прокси-сервера - PKOdev.NET Stall Server.

 

 

Внимание! Сервер находится на стадии разработки и не предназначен для применения в "продакшене". Это означает что приложение полностью не протестировано и может содержать ошибки, баги и критические уязвимости.

 

 

Возможности

 

1) Система оффлайн ларьков;

2) Ограничение количества оффлайн ларьков с одного IP-адреса;

3) Ограничение времени торговли в оффлайн-ларьке;

4) Автоматическое отключение аккаунта, торгующего в оффлайн ларьке, при подключении игрока с использованием того же аккаунта;

5) Оповещение игроков в чат о том, что персонаж находится в оффлайн ларьке и в данный момент не в сети (при обращении в ЛС);

6) Исправление SQL-инъекций в пакетах авторизации и создания (смены) секретного кода;

7) Установка максимального числа подключений к серверу с одного IP-адреса и интервала между подключениями.

 

 

To-do:

 

1) Перевод комментариев в файлах Server.h and Server.cpp на английский язык;

2) Исправление падения сервера при обработке пакетов от клиента;

3) Исправление падения сервера при запуске, когда локальный порт занят;

4) Исправление зависания моста при блокировке пакета при включенном шифровании (спасибо @small666 за обнаруженный баг);

5) Синхронизация между потоками при обработке пакетов;

6) Закрытие оффлайн ларька, если все предметы проданы;

7) Модификация GateServer.exe для определения IP-адресов клиентов, которые находятся за сервером оффлайн ларьков. В данный момент в логах и базе данных IP-адреса всех клиентов будут записываться как 127.0.0.1 (если GateServer.exe и pkodev.stallserver.exe запущены на одной машине).

8 ) Совместимость с исходным кодом Corsairs Online (CO).

 

 

Сборка и запуск

 

1) Выполните клонирование репозитория с проектом сервера к себе на диск (ссылка будет ниже);

2) Откройте файл решения pkodev.stallserver.sln в Visual Studio 2022 Community;

3) Соберите решение. Исполняемые файлы сервера появятся в папке bin;

4) Поместите конфигурационный файл pkodev.stallserver.cfg из папки cfg в одну директорию с исполняемым файлом сервера pkodev.stallserver.exe;

5) Настройте конфигурационный файл pkodev.stallserver.cfg по своему усмотрению (файл хорошо прокомментирован);

6) Для подключения игрового клиента (Game.exe) к серверу оффлайн ларьков нужно установить мод pkodev.mod.stallserver;

7) Для подключения сервера оффлайн ларьков к GateServer.exe, последний должен быть без каких-либо модификаций ("чистым"), например, из сборки PKO 1.38;

8 ) Запустите исполняемый файл сервера оффлайн ларьков pkodev.stallserver.exe.

 

Репозиторий Git

 

https://github.com/V3ct0r1024/pkodev.stallserver

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Профит в прослойке между клиентом и gateserver'ом сомнителен при условии наличия исходников последнего. Разобрать пакет, потом собрать и отправить чтобы потом разобрать...

Внутри микро-сервисной архитектуры (gate, group, account, game) пакеты передаются не зашифрованные для экономии времени обработки пакета.

 

GateServer имеет совсем крошечный функционал, было бы чудесно перенести его функционал внутрь stallserver'a и не использовать сервис Gate.

 

А так, очень круто! Наконец-то stallserver попал в публичный репозиторий, ждите пулл реквестов :)

Радует наличие мьютексов и умных указателей.

  • Thanks 1

Share this post


Link to post
Share on other sites
16 hours ago, Kst said:

Профит в прослойке между клиентом и gateserver'ом сомнителен при условии наличия исходников последнего.

Изначально проект затевался под работу с официальными бинарями сервера, да и в те времена исходники были плохо изучены и не использовались. Это был 2017 год.

 

16 hours ago, Kst said:

Разобрать пакет, потом собрать и отправить чтобы потом разобрать...

Внутри микро-сервисной архитектуры (gate, group, account, game) пакеты передаются не зашифрованные для экономии времени обработки пакета.

Я не измерял время разбора и шифрования пакетов, но думаю, что оно очень мало и им можно пренебречь. Тем более, учитывая малый FPS сервера (15-20) и наличие пинга между клиентами и сервером. 


Share this post


Link to post
Share on other sites

10.03.2022

 

+ Выполнен перевод комментариев в файлах Server.h and Server.cpp на английский язык;

+ Исправлено падение сервера при обработке пакетов от клиента. Проблема была в процедуре чтения строк из буфера, когда парсер пытался прочитать строку с нулевой длиной;

+ Исправлен краш при остановке сервера из-за некорректного порядка освобождения ресурсов;

+ Мелкие незначительные правки кода.

 

Все изменения залиты в репозиторий проекта на Github. Прошу заинтересованных пользователей заняться тестированием pkodev.stallserver.exe и отправлять в данную тему отчеты. Возможно, кто-нибудь запустит его на своем тестовом сервере. Благодарю за любую помощь!


Share this post


Link to post
Share on other sites

Простите за нубо просьбу. А можно пояснения по настройке портов как правильно подключить и порядок запуска. 

У меня либо  GateServer.exe не запускается либо StallServer.exe закрывается вообщем что то я не так делаю 😃

Edited by small666

Share this post


Link to post
Share on other sites
5 часов назад, small666 сказал:

Простите за нубо просьбу. А можно пояснения по настройке портов как правильно подключить и порядок запуска. 

У меня либо  GateServer.exe не запускается либо StallServer.exe закрывается вообщем что то я не так делаю 😃

Такое бывает когда они занимают один и тот же порт. 
Gate должен слушать условно 1973Stall должен слушать условно 7777  и перенаправлять в 1973.
Возможно вы запускаете Gate и Stall и оба они должны слушать 1973 порт. 

 

Без конфигов сложно что-либо сказать. 

  • Like 1

Наш телеграмм канал: https://t.me/kara_team_news

Share this post


Link to post
Share on other sites
[Main]
Name			= PKO138
Version			= 136

[GroupServer]
IP				= 127.0.0.1
Port			= 1976
EnablePing		= 180

[ToClient]
IP				= 0.0.0.0
Port			= 1973
CommEncrypt		= 1
EnablePing		= 60
MaxConnection	= 1000

[ToGameServer]
IP				= 127.0.0.1
Port			= 1971
EnablePing		= 180

[ShowRange]
ShowMin			= 500
ShowMax			= 800
IsUse			= 1

Stall

//
// Stall Server version 4.0 configuration file
// 
// (C) V3ct0r from PKODev.NET
// 09/20/2021
// https://pkodev.net/profile/3-v3ct0r/
//
// Syntax:
//
//   [section0]
//   key0 = value0
//   key0 = value1
//   key1 = value2
//   ...
//   [section1]
//   key2 = value3
//   ...
// 
// Multiple identical keys for a parameter are supported:
// 
//   map = garner
//   map = magicsea
//   map = darkblue
//   ...
//
// Allowed commenting characters:
//
//   '\\', '//' and '#'
//
// Supported data types:
//
//   'integer', 'double', 'boolean' and 'string'
//
// Boolean constants: 
//
//   'true', 'false', '1', '0'
//
// Note:
//
//    File: Client\scripts\lua\forms\player.clu
//     Change line (~579) 
//       UI_FormSetIsEscClose(frmFound, FALSE)
//     to
//       UI_FormSetIsEscClose(frmBooth, FALSE)
//    Now pressing the ESC key will not cancel set stall.
// 
// Thanks for using Stall Server!
//


[ToClient]
host                = 0.0.0.0  // [string]  IP address Game.exe -> StallServer.exe
port                = 1973     // [integer] Port       Game.exe -> StallServer.exe
max_player          = 2048     // [integer] The maximum number of clients that can simultaneously connect to the server
max_clients_per_ip  = 64       // [integer] The maximum number of connections from one IP address (0 = limit is disabled)
connection_interval = 1000	   // [integer] Time interval between connections from one IP address in milliseconds (0 = limit is disabled)

[ToGate]
host = 127.0.0.1              // [string]  IP address StallServer.exe -> GateServer.exe
port = 2715                   // [integer] Port       StallServer.exe -> GateServer.exe

[Map]                         // [string]  List of maps on which the offline stall system works
map = garner
map = magicsea
map = darkblue          

[Game]
max_stalls_per_ip = 0         // [integer] Max offline stall per IP (0 = disabled)
max_offline_time  = 0         // [integer] Max trading time for offline stall in seconds (0 = disabled)

Gameserver

[ID]
name			= GameServer00
equment			= system

[Gate]
gate			= 127.0.0.1, 1971

[Map]

 

Share this post


Link to post
Share on other sites

Ну про что я и писал выше
Должно быть Stall.cfg

[ToClient]
host                = 0.0.0.0  // [string]  IP address Game.exe -> StallServer.exe
port                = 7777     // [integer] Port       Game.exe -> StallServer.exe
...
[ToGate]
host = 127.0.0.1              // [string]  IP address StallServer.exe -> GateServer.exe
port = 1973  

При этом клиент должен подключаться по 7777 порту. 

Если не хотите менять внешний порт для клиента, то делаем иначе:
Stall.cfg

[ToClient]
host                = 0.0.0.0  // [string]  IP address Game.exe -> StallServer.exe
port                = 1973     // [integer] Port       Game.exe -> StallServer.exe
max_player          = 2048     // [integer] The maximum number of clients that can simultaneously connect to the server
max_clients_per_ip  = 64       // [integer] The maximum number of connections from one IP address (0 = limit is disabled)
connection_interval = 1000	   // [integer] Time interval between connections from one IP address in milliseconds (0 = limit is disabled)

[ToGate]
host = 127.0.0.1              // [string]  IP address StallServer.exe -> GateServer.exe
port = 2715                   // [integer] Port       StallServer.exe -> GateServer.exe


Gate.cfg

[ToClient]
IP				= 0.0.0.0
Port			= 2715
CommEncrypt		= 1
EnablePing		= 60
MaxConnection	= 1000

 

Поясню - для Gate клиентом является не сам клиент, а Stall. Для Stall клиентом является пользователь. Получается пользователь подключается по 1973 порту, а после перенаправляется на 2715 на Gate. 

 

 
 

  • Thanks 3

Наш телеграмм канал: https://t.me/kara_team_news

Share this post


Link to post
Share on other sites
23 часа назад, V3ct0r сказал:

10.03.2022

 

Все изменения залиты в репозиторий проекта на Github. Прошу заинтересованных пользователей заняться тестированием pkodev.stallserver.exe и отправлять в данную тему отчеты. Возможно, кто-нибудь запустит его на своем тестовом сервере. Благодарю за любую помощь!

Здравствуй V3ct0r. Установил себе на тест благодарю за помощь Kara Online 

Сам Stallserver работает при закрытии клиента персонаж торгует.

Но вот есть проблема в торг могу выставлять предметы с ID от 1 до 38 , с выше от 39 вылет клиента....🙄

P/s Сервер 138 ; Клиент 13x_1

Edited by small666
  • Thanks 1

Share this post


Link to post
Share on other sites

Привет, @small666!

 

Не наблюдаю такого бага. Уверен, что это из-за сервера оффлайн ларьков?

В каком смысле происходит "вылет клиента"? Он закрывается или просто отключается от сервера?

 


Share this post


Link to post
Share on other sites
1 час назад, V3ct0r сказал:

Привет, @small666!

 

Не наблюдаю такого бага. Уверен, что это из-за сервера оффлайн ларьков?

В каком смысле происходит "вылет клиента"? Он закрывается или просто отключается от сервера?

 

Конфликтует с модом pkodev.mod.reward.client.13x_1

закрывается клиент

Edited by small666

Share this post


Link to post
Share on other sites

V3ct0r 

Нашел еще баг .

Удалил все моды кроме StallServer для чистоты эксперимента.

По этапно

1-й персонаж в оффлайне торгует

2-м персонажем подходим все ок работает мобы бьются лоток просматривается. Но если данным персонажем обратится в лс к первому персонажу что торгует в чате сообщение This player is offline now! и 2-й персонаж больше не может просматривать лоток атаковать мобов передвигаться по локации но при всем этом он не отключен от сервера сообщения в мес. чат проходят из инвенторя предмет выбрасывается и подбирается обратно......🤪

 

Edited by small666
  • Thanks 1

Share this post


Link to post
Share on other sites
1 час назад, small666 сказал:

V3ct0r 

Нашел еще баг .

Удалил все моды кроме StallServer для чистоты эксперимента.

По этапно

1-й персонаж в оффлайне торгует

2-м персонажем подходим все ок работает мобы бьются лоток просматривается. Но если данным персонажем обратится в лс к первому персонажу что торгует в чате сообщение This player is offline now! и 2-й персонаж больше не может просматривать лоток атаковать мобов передвигаться по локации но при всем этом он не отключен от сервера сообщения в мес. чат проходят из инвенторя предмет выбрасывается и подбирается обратно......🤪

 

В общем такая ерунда происходит при обращении в ЛС ; В друзья ; В отряд.

С функцией ментор ; дуэль ; торг ; такой проблемы нет

  • Thanks 1

Share this post


Link to post
Share on other sites

Привет, @small666

 

21 hours ago, small666 said:

Конфликтует с модом pkodev.mod.reward.client.13x_1

закрывается клиент

А если открыть ларек с этой модификацией, но без сервера оффлайн ларьков? Возможно, проблема в моде, а не сервере.

 

21 hours ago, small666 said:

V3ct0r 

Нашел еще баг .

Удалил все моды кроме StallServer для чистоты эксперимента.

По этапно

1-й персонаж в оффлайне торгует

2-м персонажем подходим все ок работает мобы бьются лоток просматривается. Но если данным персонажем обратится в лс к первому персонажу что торгует в чате сообщение This player is offline now! и 2-й персонаж больше не может просматривать лоток атаковать мобов передвигаться по локации но при всем этом он не отключен от сервера сообщения в мес. чат проходят из инвенторя предмет выбрасывается и подбирается обратно......🤪

 

У меня не получилось воспроизвести и этот баг. Можешь написать какие у тебя моды установлены в клиенте? И если их все отключить (кроме pkodev.mod.stallserver), будет ли работать? Есть ли в Game.exe какие-либо патчи, не относящиеся к модам pkodev.mod.loader?

 

 

Благодарю за обратную связь!


Share this post


Link to post
Share on other sites
38 минут назад, V3ct0r сказал:

У меня не получилось воспроизвести и этот баг. Можешь написать какие у тебя моды установлены в клиенте? И если их все отключить (кроме pkodev.mod.stallserver), будет ли работать? Есть ли в Game.exe какие-либо патчи, не относящиеся к модам pkodev.mod.loader?

В Game.exe есть изменения на лимит аппарелей по статье плавка аппарелей установлен лимит до 15000.

Что касаемо установленных модов я их все выкинул из клиента и сервера оставив только pkodev.mod.stallserver и при оброщении персонажем в ( ЛС ; Дружба ; Отряд ) к персонажу торгующий в оффлайне происходит  данный баг.

 

57 минут назад, V3ct0r сказал:

 

А если открыть ларек с этой модификацией, но без сервера оффлайн ларьков? Возможно, проблема в моде, а не сервере.

 

Да вы правы проблема в моде pkodev.mod.reward.client.13x_1 

 

P/s Если поможет могу скинуть сервер и клиент Вам 😃

  • Thanks 1

Share this post


Link to post
Share on other sites
On 3/12/2022 at 2:07 PM, small666 said:

P/s Если поможет могу скинуть сервер и клиент Вам 😃

Было бы хорошо


Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Привет, @small666!

 

Я проверил работу сервера ларьков используя твои сборку и клиент. Действительно, такой баг присутствовал. Я его не обнаружил из-за того, что у меня было отключено шифрование пакетов в GateServer.cfg, а он проявлялся только при включенном шифровании. Данный баг был исправлен. Огромное спасибо за помощь!

 

 

18.04.2022

 

+ Исправлено зависание моста при блокировке пакетов при включенном шифровании в GateServer.cfg (спасибо @small666 за обнаруженный баг);

+ Сделана синхронизация потоков;

+ Оптимизация кода и прочие незначительные изменения.

 

Все изменения залиты в репозиторий проекта на GitHub. По-прежнему буду благодарен за любую помощь в разработке, особенно за тестирование.

  • Thanks 1

Share this post


Link to post
Share on other sites
9 часов назад, V3ct0r сказал:

Привет, @small666!

 

Я проверил работу сервера ларьков используя твои сборку и клиент. Действительно, такой баг присутствовал. Я его не обнаружил из-за того, что у меня было отключено шифрование пакетов в GateServer.cfg, а он проявлялся только при включенном шифровании. Данный баг был исправлен. Огромное спасибо за помощь!

 

 

18.04.2022

 

+ Исправлено зависание моста при блокировке пакетов при включенном шифровании в GateServer.cfg (спасибо @small666 за обнаруженный баг);

+ Сделана синхронизация потоков;

+ Оптимизация кода и прочие незначительные изменения.

 

Все изменения залиты в репозиторий проекта на GitHub. По-прежнему буду благодарен за любую помощь в разработке, особенно за тестирование.

Вам большое спасибо 

Share this post


Link to post
Share on other sites

21.04.2022

 

+ Проект переведен на версию Visual Studio Community 2022;

+ Добавлена возможность автоматического закрытия оффлайн ларька, если он стал пустым (все предметы проданы). Данное поведение включается и отключается с помощью параметра 'close_stall_on_empty' в конфигурационном файле 'pkodev.stallserver.cfg';

+ Отправка IP-адреса клиента в логин-пакете на игровой сервер для определения IP-адресов игроков за StallServer. Для GateServer должно быть установлено соответствующее расширение. Данное поведение включается и отключается с помощью параметра 'ip_mod' в конфигурационном файле 'pkodev.stallserver.cfg';

+ Незначительные исправления кода и прочие мелкие изменения.

 

Все изменения залиты в репозиторий проекта на GitHub.  Не забудьте обновить конфигурационный файл  'pkodev.stallserver.cfg'.

  • Thanks 1

Share this post


Link to post
Share on other sites

05.05.2022

 

+ Добавлены консольные команды для управления сервером;

1) '/close' - Stop the server.
2) '/disconnect' - Disconnect clients: [all] - all clients; [offline] - offline stalls only.
3) '/help' - Show available console commands.
4) '/kick' - Disconnect a client by character name or account: [character] [character name] - by character name; [account] [account name] - by account.
5) '/notice' - Send a message to the system chat channel to all connected clients.
6) '/stat' - Show server statistics.
7) '/stop' - Stop the server.

stallserver_update050522.png

 

+ Сделано уменьшение числа задач у рабочих потоков при отключении клиента от сервера;

+ Исправлено отключение клиента от сервера в методе void Bridge::disconnect();

+ Незначительные исправления кода и прочие мелкие изменения.

 

 

Все изменения залиты в репозиторий проекта на GitHub.

  • Thanks 1

Share this post


Link to post
Share on other sites
3 часа назад, V3ct0r сказал:

05.05.2022

 

+ Добавлены консольные команды для управления сервером;

1) '/close' - Stop the server.
2) '/disconnect' - Disconnect clients: [all] - all clients; [offline] - offline stalls only.
3) '/help' - Show available console commands.
4) '/kick' - Disconnect a client by character name or account: [character] [character name] - by character name; [account] [account name] - by account.
5) '/notice' - Send a message to the system chat channel to all connected clients.
6) '/stat' - Show server statistics.
7) '/stop' - Stop the server.

 

5) '/notice' - Send a message to the system chat channel to all connected clients.

 

Отправляет только английские буквы с русским кодируется в oem код , пробывал отправлять в oem вообще не отправляет выдает ошибку в консоле мыл нет такой команды

  • Thanks 1

Share this post


Link to post
Share on other sites

@small666,

 

Добавь в самом начале функции main() следующий код:

SetConsoleCP(1251);

 

Чтобы получилось примерно так:

. . .

// Entry point
int main(int argc, char *argv[])
{
    SetConsoleCP(1251);

    // Disable <CTRL> key handling
    SetConsoleCtrlHandler(nullptr, TRUE);
      
. . .

 

  • Thanks 1

Share this post


Link to post
Share on other sites
4 минуты назад, V3ct0r сказал:

@small666,

 

Добавь в самом начале функции main() следующий код:

SetConsoleCP(1251);

 

Чтобы получилось примерно так:

. . .

// Entry point
int main(int argc, char *argv[])
{
    SetConsoleCP(1251);

    // Disable <CTRL> key handling
    SetConsoleCtrlHandler(nullptr, TRUE);
      
. . .

 

Спасибо помогло

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...