Add Essence 520 minimal DB, configs, and login/game Docker profile.
This commit is contained in:
+14
-4
@@ -1,9 +1,19 @@
|
|||||||
# Скопируйте в .env (install.sh создаст .env сам).
|
# PostgreSQL
|
||||||
# В паролях для docker compose символ $ нужно удваивать: pa$$word
|
|
||||||
POSTGRES_USER=l2user
|
POSTGRES_USER=l2user
|
||||||
POSTGRES_PASSWORD=change_me_strong_password
|
POSTGRES_PASSWORD=change_me_strong_password
|
||||||
POSTGRES_DB=l2essence
|
POSTGRES_DB=l2essence
|
||||||
POSTGRES_PORT=5432
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
# Образ игрового сервера (когда будет свой реестр/локальная сборка)
|
# Клиент Essence protocol 520
|
||||||
# L2_SERVER_IMAGE=your-registry/l2-essence-542:latest
|
L2_PROTOCOL=520
|
||||||
|
|
||||||
|
# Порты (профиль docker compose --profile l2)
|
||||||
|
L2_LOGIN_PORT=2106
|
||||||
|
L2_LOGIN_GS_PORT=9014
|
||||||
|
L2_GAME_PORT=7777
|
||||||
|
|
||||||
|
# Образы Java для Login/Game (если используете profile l2)
|
||||||
|
# L2_LOGIN_IMAGE=eclipse-temurin:21-jre
|
||||||
|
# L2_GAME_IMAGE=eclipse-temurin:21-jre
|
||||||
|
|
||||||
|
# В паролях для docker compose символ $ удваивайте: pa$$word
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Lineage 2 Essence — Game Server (шаблон, клиент protocol 520)
|
||||||
|
# Скопируйте в dist/game/config/ вашей сборки.
|
||||||
|
|
||||||
|
LoginHost = login
|
||||||
|
LoginPort = 9014
|
||||||
|
GameserverHostname = *
|
||||||
|
GameserverPort = 7777
|
||||||
|
|
||||||
|
RequestServerID = 1
|
||||||
|
AcceptAlternateID = True
|
||||||
|
MaximumOnlineUsers = 500
|
||||||
|
DatapackRoot = .
|
||||||
|
|
||||||
|
# Только клиент 520 (Essence)
|
||||||
|
AllowedProtocolRevisions = 520
|
||||||
|
|
||||||
|
Driver = org.postgresql.Driver
|
||||||
|
URL = jdbc:postgresql://postgres:5432/l2essence
|
||||||
|
Login = l2user
|
||||||
|
Password = change_me_strong_password
|
||||||
|
MaximumDbConnections = 100
|
||||||
|
|
||||||
|
CharMaxNumber = 7
|
||||||
|
CnameTemplate = .*
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# HexID = RequestServerID 1 (должен совпадать с gameservers.hexid в БД)
|
||||||
|
HexID=a1b2c3d4e5f6789012345678901234ef
|
||||||
|
ServerID=1
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../data/xsd/ipconfig.xsd">
|
||||||
|
<host subnet="0.0.0.0/0" address="127.0.0.1" />
|
||||||
|
</list>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Lineage 2 Essence — Login Server (шаблон под Docker + PostgreSQL 17)
|
||||||
|
# Скопируйте в dist/login/config/ вашей сборки Samurai Crow / Mobius Essence.
|
||||||
|
|
||||||
|
LoginserverHostname = *
|
||||||
|
LoginserverPort = 2106
|
||||||
|
LoginHostname = 0.0.0.0
|
||||||
|
LoginPort = 9014
|
||||||
|
|
||||||
|
LoginTryBeforeBan = 5
|
||||||
|
LoginBlockAfterBan = 900
|
||||||
|
AcceptNewGameServer = True
|
||||||
|
EnableFloodProtection = True
|
||||||
|
AutoCreateAccounts = True
|
||||||
|
ShowLicence = False
|
||||||
|
|
||||||
|
# PostgreSQL (хост postgres — имя сервиса в docker-compose)
|
||||||
|
Driver = org.postgresql.Driver
|
||||||
|
URL = jdbc:postgresql://postgres:5432/l2essence
|
||||||
|
Login = l2user
|
||||||
|
Password = change_me_strong_password
|
||||||
|
MaximumDbConnections = 50
|
||||||
|
|
||||||
|
DatapackRoot = .
|
||||||
|
Debug = False
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../data/xsd/ipconfig.xsd">
|
||||||
|
<!-- Внешний IP для клиента (замените на IP вашего VPS) -->
|
||||||
|
<host subnet="0.0.0.0/0" address="127.0.0.1" />
|
||||||
|
</list>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<servers>
|
||||||
|
<server id="1" name="Essence 520" />
|
||||||
|
</servers>
|
||||||
+35
-16
@@ -1,5 +1,5 @@
|
|||||||
# Lineage 2 Essence 542 (Samurai Crow) — локальная среда
|
# Lineage 2 Essence — клиент protocol 520, PostgreSQL 17
|
||||||
# Замените сервис l2-server на свой образ/сборку, когда будет готов Dockerfile.
|
# БД: login + game в одной БД. JAR Login/Game — в ./server (см. config/).
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
@@ -22,23 +22,42 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
# Заглушка: подключите свой сервер (Auth/Game) или замените build: на реальный Dockerfile.
|
# Подключите сборку Samurai Crow / Mobius Essence (520):
|
||||||
l2-server:
|
# положите login/game в ./server/login и ./server/game, раскомментируйте сервисы.
|
||||||
image: ${L2_SERVER_IMAGE:-ubuntu:24.04}
|
login:
|
||||||
container_name: l2_server_placeholder
|
profiles: ["l2"]
|
||||||
restart: "no"
|
image: ${L2_LOGIN_IMAGE:-eclipse-temurin:21-jre}
|
||||||
|
container_name: l2_login
|
||||||
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
working_dir: /opt/l2/login
|
||||||
DATABASE_URL: postgresql://${POSTGRES_USER:-l2user}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-l2essence}
|
volumes:
|
||||||
# Раскомментируйте при готовности бинарей/скриптов:
|
- ./server/login:/opt/l2/login
|
||||||
# volumes:
|
- ./config/login:/opt/l2/login/config:ro
|
||||||
# - ./server:/opt/l2server:ro
|
ports:
|
||||||
# command: ["/opt/l2server/start.sh"]
|
- "${L2_LOGIN_PORT:-2106}:2106"
|
||||||
command: ["bash", "-lc", "echo 'L2 server placeholder: замените сервис l2-server в docker-compose.yml'; sleep infinity"]
|
- "${L2_LOGIN_GS_PORT:-9014}:9014"
|
||||||
profiles:
|
command: ["bash", "-lc", "test -f ./LoginServer.jar && java -jar LoginServer.jar || echo 'Нет LoginServer.jar в server/login'; sleep infinity"]
|
||||||
- placeholder
|
|
||||||
|
game:
|
||||||
|
profiles: ["l2"]
|
||||||
|
image: ${L2_GAME_IMAGE:-eclipse-temurin:21-jre}
|
||||||
|
container_name: l2_game
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
login:
|
||||||
|
condition: service_started
|
||||||
|
working_dir: /opt/l2/game
|
||||||
|
volumes:
|
||||||
|
- ./server/game:/opt/l2/game
|
||||||
|
- ./config/game:/opt/l2/game/config:ro
|
||||||
|
ports:
|
||||||
|
- "${L2_GAME_PORT:-7777}:7777"
|
||||||
|
command: ["bash", "-lc", "test -f ./GameServer.jar && java -jar GameServer.jar || echo 'Нет GameServer.jar в server/game'; sleep infinity"]
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
-- Login DB: L2J Mobius / Essence (совместимость с клиентом protocol 520).
|
||||||
|
-- Пароль: Base64(SHA1(UTF-8 пароль)) — см. LoginController Mobius.
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS accounts (
|
||||||
|
login VARCHAR(45) NOT NULL PRIMARY KEY,
|
||||||
|
password VARCHAR(45),
|
||||||
|
lastactive BIGINT,
|
||||||
|
"accessLevel" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"lastIP" VARCHAR(20),
|
||||||
|
"lastServer" INTEGER DEFAULT 1,
|
||||||
|
"pcIp" VARCHAR(20),
|
||||||
|
hop1 VARCHAR(20),
|
||||||
|
hop2 VARCHAR(20),
|
||||||
|
hop3 VARCHAR(20),
|
||||||
|
hop4 VARCHAR(20)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS account_data (
|
||||||
|
account_name VARCHAR(45) NOT NULL,
|
||||||
|
var VARCHAR(20) NOT NULL,
|
||||||
|
value VARCHAR(255),
|
||||||
|
PRIMARY KEY (account_name, var),
|
||||||
|
CONSTRAINT fk_account_data_login FOREIGN KEY (account_name)
|
||||||
|
REFERENCES accounts (login) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS accounts_ipauth (
|
||||||
|
login VARCHAR(45) NOT NULL,
|
||||||
|
ip VARCHAR(15) NOT NULL,
|
||||||
|
type VARCHAR(15) NOT NULL,
|
||||||
|
PRIMARY KEY (login, ip)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS gameservers (
|
||||||
|
server_id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
hexid VARCHAR(50) NOT NULL,
|
||||||
|
host VARCHAR(50) NOT NULL
|
||||||
|
);
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
-- Минимальные таблицы под логин-сервер в стиле L2J (accounts / gameservers / account_data).
|
|
||||||
-- Подходит для многих форков; у Samurai Crow/Essence могут отличаться имена колонок или хеш пароля —
|
|
||||||
-- тогда сверьте с SQL из вашей сборки и поправьте этот файл.
|
|
||||||
--
|
|
||||||
-- Тестовый логин: admin / admin
|
|
||||||
-- Хеш: Base64(SHA1 от UTF-8 строки «admin») — типично для L2J/Mobius.
|
|
||||||
-- Альтернатива (если сборка ждёт hex SHA1): замените поле password на
|
|
||||||
-- d033e22ae348aeb5660fc2140aec35850c4da997
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS accounts (
|
|
||||||
login VARCHAR(45) NOT NULL PRIMARY KEY,
|
|
||||||
password VARCHAR(128),
|
|
||||||
lastactive BIGINT,
|
|
||||||
accesslevel INTEGER NOT NULL DEFAULT 0,
|
|
||||||
lastip VARCHAR(45),
|
|
||||||
lastserver SMALLINT DEFAULT 1
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS account_data (
|
|
||||||
account_name VARCHAR(45) NOT NULL,
|
|
||||||
var VARCHAR(50) NOT NULL,
|
|
||||||
value VARCHAR(255),
|
|
||||||
PRIMARY KEY (account_name, var),
|
|
||||||
CONSTRAINT fk_account_data_account FOREIGN KEY (account_name)
|
|
||||||
REFERENCES accounts (login) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS gameservers (
|
|
||||||
hexid VARCHAR(255) NOT NULL,
|
|
||||||
server_id INTEGER NOT NULL PRIMARY KEY,
|
|
||||||
host VARCHAR(255) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO accounts (login, password, lastactive, accesslevel, lastip, lastserver)
|
|
||||||
VALUES (
|
|
||||||
'admin',
|
|
||||||
'0DPiKuNIrrVmD8IUCuw1hQxNqZc=',
|
|
||||||
(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint,
|
|
||||||
0,
|
|
||||||
'127.0.0.1',
|
|
||||||
1
|
|
||||||
)
|
|
||||||
ON CONFLICT (login) DO NOTHING;
|
|
||||||
|
|
||||||
-- Игровой сервер при первом подключении к логину часто сам делает INSERT в gameservers.
|
|
||||||
-- Если нужна явная запись (hexid должен совпасть с RequestServerID / hex в конфиге GS):
|
|
||||||
-- INSERT INTO gameservers (hexid, server_id, host)
|
|
||||||
-- VALUES ('ВАШ_32_СИМВОЛА_HEX', 1, '127.0.0.1')
|
|
||||||
-- ON CONFLICT (server_id) DO UPDATE SET hexid = EXCLUDED.hexid, host = EXCLUDED.host;
|
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
-- Game DB (та же БД): минимум для экрана выбора/создания персонажа и входа в мир.
|
||||||
|
-- Полный дамп datapack ставьте поверх, если сборка Samurai Crow требует больше таблиц.
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS global_data (
|
||||||
|
var VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||||
|
value TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS characters (
|
||||||
|
account_name VARCHAR(45),
|
||||||
|
charId INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
char_name VARCHAR(35) NOT NULL,
|
||||||
|
level SMALLINT DEFAULT 1,
|
||||||
|
maxHp INTEGER DEFAULT 100,
|
||||||
|
curHp INTEGER DEFAULT 100,
|
||||||
|
maxCp INTEGER DEFAULT 100,
|
||||||
|
curCp INTEGER DEFAULT 100,
|
||||||
|
maxMp INTEGER DEFAULT 100,
|
||||||
|
curMp INTEGER DEFAULT 100,
|
||||||
|
face SMALLINT DEFAULT 0,
|
||||||
|
hairStyle SMALLINT DEFAULT 0,
|
||||||
|
hairColor SMALLINT DEFAULT 0,
|
||||||
|
sex SMALLINT DEFAULT 0,
|
||||||
|
reputation INTEGER DEFAULT 0,
|
||||||
|
fame INTEGER DEFAULT 0,
|
||||||
|
raidbossPoints INTEGER DEFAULT 0,
|
||||||
|
pvpkills INTEGER DEFAULT 0,
|
||||||
|
pkkills INTEGER DEFAULT 0,
|
||||||
|
clanid INTEGER DEFAULT 0,
|
||||||
|
race SMALLINT DEFAULT 0,
|
||||||
|
classid INTEGER DEFAULT 0,
|
||||||
|
deletetime BIGINT DEFAULT 0,
|
||||||
|
title VARCHAR(21) DEFAULT '',
|
||||||
|
accesslevel INTEGER DEFAULT 0,
|
||||||
|
online SMALLINT DEFAULT 0,
|
||||||
|
onlinetime INTEGER DEFAULT 0,
|
||||||
|
char_slot SMALLINT DEFAULT 0,
|
||||||
|
lastAccess BIGINT DEFAULT 0,
|
||||||
|
clan_privs INTEGER DEFAULT 0,
|
||||||
|
wantspeace SMALLINT DEFAULT 0,
|
||||||
|
base_class INTEGER DEFAULT 0,
|
||||||
|
x INTEGER DEFAULT -114520,
|
||||||
|
y INTEGER DEFAULT -249704,
|
||||||
|
z INTEGER DEFAULT -2984,
|
||||||
|
heading INTEGER DEFAULT 0,
|
||||||
|
createDate DATE DEFAULT CURRENT_DATE,
|
||||||
|
isIn7sDungeon SMALLINT DEFAULT 0,
|
||||||
|
in_jail SMALLINT DEFAULT 0,
|
||||||
|
jail_timer INTEGER DEFAULT 0,
|
||||||
|
powerGrade SMALLINT DEFAULT 0,
|
||||||
|
apprentice INTEGER DEFAULT 0,
|
||||||
|
sponsor INTEGER DEFAULT 0,
|
||||||
|
clan_join_expiry_time TIMESTAMP NULL,
|
||||||
|
clan_create_expiry_time TIMESTAMP NULL,
|
||||||
|
bookmarkslot SMALLINT DEFAULT 0,
|
||||||
|
vitality_points INTEGER DEFAULT 35000,
|
||||||
|
language VARCHAR(5) DEFAULT 'en'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_characters_account ON characters (account_name);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_characters_name ON characters (char_name);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS character_subclasses (
|
||||||
|
charId INTEGER NOT NULL,
|
||||||
|
class_id INTEGER NOT NULL DEFAULT 0,
|
||||||
|
exp BIGINT DEFAULT 0,
|
||||||
|
sp BIGINT DEFAULT 0,
|
||||||
|
level INTEGER DEFAULT 1,
|
||||||
|
class_index INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (charId, class_index),
|
||||||
|
CONSTRAINT fk_subclasses_char FOREIGN KEY (charId)
|
||||||
|
REFERENCES characters (charId) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS character_skills (
|
||||||
|
charId INTEGER NOT NULL,
|
||||||
|
skill_id INTEGER NOT NULL,
|
||||||
|
skill_level INTEGER NOT NULL DEFAULT 1,
|
||||||
|
class_index INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (charId, skill_id, class_index),
|
||||||
|
CONSTRAINT fk_skills_char FOREIGN KEY (charId)
|
||||||
|
REFERENCES characters (charId) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS character_shortcuts (
|
||||||
|
charId INTEGER NOT NULL,
|
||||||
|
slot INTEGER NOT NULL,
|
||||||
|
page INTEGER NOT NULL,
|
||||||
|
type INTEGER DEFAULT 0,
|
||||||
|
shortcut_id INTEGER DEFAULT 0,
|
||||||
|
level INTEGER DEFAULT 0,
|
||||||
|
class_index INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (charId, slot, page, class_index),
|
||||||
|
CONSTRAINT fk_shortcuts_char FOREIGN KEY (charId)
|
||||||
|
REFERENCES characters (charId) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS character_variables (
|
||||||
|
charId INTEGER NOT NULL,
|
||||||
|
var VARCHAR(255) NOT NULL,
|
||||||
|
val TEXT,
|
||||||
|
PRIMARY KEY (charId, var),
|
||||||
|
CONSTRAINT fk_variables_char FOREIGN KEY (charId)
|
||||||
|
REFERENCES characters (charId) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS items (
|
||||||
|
object_id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
owner_id INTEGER NOT NULL,
|
||||||
|
item_id INTEGER NOT NULL,
|
||||||
|
count BIGINT NOT NULL DEFAULT 1,
|
||||||
|
enchant_level INTEGER DEFAULT 0,
|
||||||
|
loc VARCHAR(10) NOT NULL DEFAULT 'INVENTORY',
|
||||||
|
loc_data INTEGER DEFAULT 0
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_items_owner ON items (owner_id);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS clan_data (
|
||||||
|
clan_id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
clan_name VARCHAR(45) NOT NULL,
|
||||||
|
clan_level INTEGER DEFAULT 0,
|
||||||
|
reputation_score INTEGER DEFAULT 0,
|
||||||
|
hasCastle INTEGER DEFAULT 0,
|
||||||
|
blood_alliance INTEGER DEFAULT 0,
|
||||||
|
blood_oath INTEGER DEFAULT 0,
|
||||||
|
ally_id INTEGER DEFAULT 0,
|
||||||
|
ally_name VARCHAR(45) DEFAULT '',
|
||||||
|
leader_id INTEGER DEFAULT 0,
|
||||||
|
crest_id INTEGER DEFAULT 0,
|
||||||
|
crest_large_id INTEGER DEFAULT 0,
|
||||||
|
ally_crest_id INTEGER DEFAULT 0,
|
||||||
|
auction_bid_at INTEGER DEFAULT 0,
|
||||||
|
ally_penalty_expiry_time BIGINT DEFAULT 0,
|
||||||
|
ally_penalty_type SMALLINT DEFAULT 0,
|
||||||
|
char_penalty_expiry_time BIGINT DEFAULT 0,
|
||||||
|
dissolving_expiry_time BIGINT DEFAULT 0,
|
||||||
|
new_leader_id INTEGER DEFAULT 0
|
||||||
|
);
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Выдаёт владельца таблиц логина роли из POSTGRES_USER (см. docker-compose).
|
|
||||||
set -eu
|
|
||||||
psql -v ON_ERROR_STOP=1 --username "postgres" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
||||||
ALTER TABLE IF EXISTS accounts OWNER TO "${POSTGRES_USER}";
|
|
||||||
ALTER TABLE IF EXISTS account_data OWNER TO "${POSTGRES_USER}";
|
|
||||||
ALTER TABLE IF EXISTS gameservers OWNER TO "${POSTGRES_USER}";
|
|
||||||
EOSQL
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
-- Тестовые данные: Essence protocol 520 (логин + регистрация GS).
|
||||||
|
-- Логины: admin/admin, test/test
|
||||||
|
-- Hexid совпадает с server/hexid/default.txt
|
||||||
|
|
||||||
|
INSERT INTO global_data (var, value)
|
||||||
|
VALUES ('essence_protocol', '520')
|
||||||
|
ON CONFLICT (var) DO UPDATE SET value = EXCLUDED.value;
|
||||||
|
|
||||||
|
INSERT INTO accounts (login, password, lastactive, "accessLevel", "lastIP", "lastServer")
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
'admin',
|
||||||
|
'0DPiKuNIrrVmD8IUCuw1hQxNqZc=',
|
||||||
|
(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint,
|
||||||
|
100,
|
||||||
|
'127.0.0.1',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test',
|
||||||
|
'qUqP5cyxm6YcTAhz05Hph5gvu9M=',
|
||||||
|
(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint,
|
||||||
|
0,
|
||||||
|
'127.0.0.1',
|
||||||
|
1
|
||||||
|
)
|
||||||
|
ON CONFLICT (login) DO NOTHING;
|
||||||
|
|
||||||
|
-- RequestServerID = 1, hex из server/hexid/default.txt
|
||||||
|
INSERT INTO gameservers (server_id, hexid, host)
|
||||||
|
VALUES (1, 'a1b2c3d4e5f6789012345678901234ef', '127.0.0.1')
|
||||||
|
ON CONFLICT (server_id) DO UPDATE
|
||||||
|
SET hexid = EXCLUDED.hexid, host = EXCLUDED.host;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Владелец всех таблиц public → POSTGRES_USER (после всех *.sql).
|
||||||
|
set -eu
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "postgres" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||||
|
DO \$\$
|
||||||
|
DECLARE
|
||||||
|
t text;
|
||||||
|
BEGIN
|
||||||
|
FOR t IN SELECT tablename FROM pg_tables WHERE schemaname = 'public'
|
||||||
|
LOOP
|
||||||
|
EXECUTE format('ALTER TABLE IF EXISTS %I OWNER TO %I', t, '${POSTGRES_USER}');
|
||||||
|
END LOOP;
|
||||||
|
END \$\$;
|
||||||
|
EOSQL
|
||||||
+18
-8
@@ -50,8 +50,8 @@ read_env_val() {
|
|||||||
|
|
||||||
# --- Шаг 0: приветствие ---
|
# --- Шаг 0: приветствие ---
|
||||||
step_header "Шаг 0 — Обзор"
|
step_header "Шаг 0 — Обзор"
|
||||||
echo "Проект: Lineage 2 Essence 542 (Samurai Crow), окружение в Docker."
|
echo "Проект: Lineage 2 Essence, клиент protocol 520, PostgreSQL 17."
|
||||||
echo "Будет поднят PostgreSQL 17; игровой сервис — по профилю placeholder (заглушка), пока нет своего образа."
|
echo "БД: login + game (минимум для входа). Login/Game JAR — профиль l2 (server/login, server/game)."
|
||||||
if ! ask_yes_no "Продолжить?" "y"; then
|
if ! ask_yes_no "Продолжить?" "y"; then
|
||||||
info "Выход."
|
info "Выход."
|
||||||
exit 0
|
exit 0
|
||||||
@@ -161,6 +161,7 @@ fi
|
|||||||
step_header "Шаг 5 — Запуск PostgreSQL 17"
|
step_header "Шаг 5 — Запуск PostgreSQL 17"
|
||||||
if ask_yes_no "Поднять только PostgreSQL (рекомендуется)?" "y"; then
|
if ask_yes_no "Поднять только PostgreSQL (рекомендуется)?" "y"; then
|
||||||
chmod +x "$SCRIPT_DIR"/docker/initdb/*.sh 2>/dev/null || true
|
chmod +x "$SCRIPT_DIR"/docker/initdb/*.sh 2>/dev/null || true
|
||||||
|
chmod +x "$SCRIPT_DIR"/scripts/*.sh 2>/dev/null || true
|
||||||
docker compose up -d postgres
|
docker compose up -d postgres
|
||||||
info "Ожидание готовности PostgreSQL (pg_isready)..."
|
info "Ожидание готовности PostgreSQL (pg_isready)..."
|
||||||
EV_USER="$(read_env_val POSTGRES_USER)"
|
EV_USER="$(read_env_val POSTGRES_USER)"
|
||||||
@@ -174,11 +175,17 @@ if ask_yes_no "Поднять только PostgreSQL (рекомендуетс
|
|||||||
docker compose ps
|
docker compose ps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Шаг 6: заглушка L2 ---
|
# --- Шаг 6: конфиг и Login/Game ---
|
||||||
step_header "Шаг 6 — Игровой контейнер (заглушка)"
|
step_header "Шаг 6 — Конфиг Essence 520"
|
||||||
warn "Сервис l2-server в compose помечен profile 'placeholder'. Замените образ/команду под Samurai Crow."
|
if [[ -f "$SCRIPT_DIR/scripts/sync-config-password.sh" ]]; then
|
||||||
if ask_yes_no "Запустить контейнер-заглушку l2-server (для проверки сети к БД)?" "n"; then
|
if ask_yes_no "Подставить пароль БД из .env в config/login и config/game?" "y"; then
|
||||||
docker compose --profile placeholder up -d l2-server
|
bash "$SCRIPT_DIR/scripts/sync-config-password.sh"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
step_header "Шаг 7 — Login / Game (Docker profile l2)"
|
||||||
|
warn "Положите LoginServer.jar и GameServer.jar в server/login и server/game."
|
||||||
|
if ask_yes_no "Запустить контейнеры login + game (profile l2)?" "n"; then
|
||||||
|
docker compose --profile l2 up -d login game
|
||||||
docker compose ps
|
docker compose ps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -189,8 +196,11 @@ EV_DB="$(read_env_val POSTGRES_DB)"
|
|||||||
EV_PORT="$(read_env_val POSTGRES_PORT)"
|
EV_PORT="$(read_env_val POSTGRES_PORT)"
|
||||||
info "Строка подключения с хоста Ubuntu: postgresql://${EV_USER}:***@127.0.0.1:${EV_PORT}/${EV_DB}"
|
info "Строка подключения с хоста Ubuntu: postgresql://${EV_USER}:***@127.0.0.1:${EV_PORT}/${EV_DB}"
|
||||||
info "Из контейнеров в этой compose-сети: хост postgres, порт 5432."
|
info "Из контейнеров в этой compose-сети: хост postgres, порт 5432."
|
||||||
|
info "Тест-аккаунты: admin/admin и test/test."
|
||||||
|
info "Клиент: protocol 520, логин 127.0.0.1:2106, мир 127.0.0.1:7777."
|
||||||
echo ""
|
echo ""
|
||||||
info "Полезные команды:"
|
info "Полезные команды:"
|
||||||
echo " docker compose logs -f postgres"
|
echo " docker compose logs -f postgres"
|
||||||
|
echo " docker compose --profile l2 up -d login game"
|
||||||
|
echo " ./scripts/apply-essence-schema.sh # если БД уже была без новых таблиц"
|
||||||
echo " docker compose down"
|
echo " docker compose down"
|
||||||
echo " docker compose --profile placeholder down"
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Интерактивное управление: остановка, запуск, перезапуск Docker-сервисов проекта.
|
# Управление: PostgreSQL + Login/Game (Essence 520, profile l2).
|
||||||
# Запуск: chmod +x manage.sh && ./manage.sh
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -13,10 +12,10 @@ YELLOW='\033[1;33m'
|
|||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
ENV_FILE="$SCRIPT_DIR/.env"
|
ENV_FILE="$SCRIPT_DIR/.env"
|
||||||
PROFILE_PLACEHOLDER=(--profile placeholder)
|
PROFILE_L2=(--profile l2)
|
||||||
# Имена из docker-compose.yml (для надёжной проверки состояния)
|
|
||||||
PG_CONTAINER="l2_postgres"
|
PG_CONTAINER="l2_postgres"
|
||||||
L2_CONTAINER="l2_server_placeholder"
|
LOGIN_CONTAINER="l2_login"
|
||||||
|
GAME_CONTAINER="l2_game"
|
||||||
|
|
||||||
read_env_val() {
|
read_env_val() {
|
||||||
local key="$1"
|
local key="$1"
|
||||||
@@ -50,144 +49,107 @@ step_header() {
|
|||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
}
|
}
|
||||||
|
|
||||||
require_cmd() {
|
|
||||||
command -v "$1" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_docker() {
|
ensure_docker() {
|
||||||
if ! require_cmd docker || ! docker compose version >/dev/null 2>&1; then
|
if ! command -v docker >/dev/null 2>&1 || ! docker compose version >/dev/null 2>&1; then
|
||||||
err "Нужны Docker и плагин «docker compose». Установите через ./install.sh"
|
err "Нужны Docker и docker compose. Запустите ./install.sh"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if ! docker info >/dev/null 2>&1; then
|
if ! docker info >/dev/null 2>&1; then
|
||||||
err "Docker недоступен (sudo или перелогин после группы docker)."
|
err "Docker недоступен."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_env() {
|
ensure_env() {
|
||||||
if [[ ! -f "$ENV_FILE" ]]; then
|
if [[ ! -f "$ENV_FILE" ]]; then
|
||||||
err "Нет файла .env. Сначала выполните ./install.sh"
|
err "Нет .env. Сначала ./install.sh"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
postgres_running() {
|
container_running() {
|
||||||
[[ "$(docker inspect -f '{{.State.Running}}' "$PG_CONTAINER" 2>/dev/null || echo false)" == "true" ]]
|
[[ "$(docker inspect -f '{{.State.Running}}' "$1" 2>/dev/null || echo false)" == "true" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
l2_running() {
|
postgres_running() { container_running "$PG_CONTAINER"; }
|
||||||
[[ "$(docker inspect -f '{{.State.Running}}' "$L2_CONTAINER" 2>/dev/null || echo false)" == "true" ]]
|
login_running() { container_running "$LOGIN_CONTAINER"; }
|
||||||
}
|
game_running() { container_running "$GAME_CONTAINER"; }
|
||||||
|
|
||||||
# --- Шаг 0 ---
|
step_header "Шаг 0 — Essence 520 (PostgreSQL + Login/Game)"
|
||||||
step_header "Шаг 0 — Управление сервером (Docker Compose)"
|
|
||||||
echo "Проект: PostgreSQL 17 + опционально l2-server (profile placeholder)."
|
|
||||||
if ! ask_yes_no "Продолжить?" "y"; then
|
if ! ask_yes_no "Продолжить?" "y"; then
|
||||||
info "Выход."
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ensure_docker
|
ensure_docker
|
||||||
ensure_env
|
ensure_env
|
||||||
|
|
||||||
# --- Шаг 1: статус ---
|
step_header "Шаг 1 — Статус"
|
||||||
step_header "Шаг 1 — Текущий статус"
|
|
||||||
if ask_yes_no "Показать docker compose ps?" "y"; then
|
if ask_yes_no "Показать docker compose ps?" "y"; then
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" ps -a || true
|
docker compose ps -a || true
|
||||||
|
docker compose "${PROFILE_L2[@]}" ps -a 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Шаг 2: остановка ---
|
|
||||||
step_header "Шаг 2 — Остановка"
|
step_header "Шаг 2 — Остановка"
|
||||||
if ask_yes_no "Остановить контейнер l2-server (если был запущен с profile placeholder)?" "n"; then
|
if ask_yes_no "Остановить game и login (profile l2)?" "n"; then
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" stop l2-server 2>/dev/null || warn "l2-server не остановлен (возможно не запускался)."
|
docker compose "${PROFILE_L2[@]}" stop game login 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Остановить PostgreSQL?" "n"; then
|
||||||
if ask_yes_no "Остановить только PostgreSQL (docker compose stop postgres)?" "n"; then
|
docker compose stop postgres 2>/dev/null || true
|
||||||
docker compose stop postgres 2>/dev/null || warn "PostgreSQL уже остановлен или не создавался."
|
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "docker compose down (все сервисы, том БД сохраняется)?" "n"; then
|
||||||
if ask_yes_no "Полная остановка проекта: docker compose down (все сервисы, сеть; тома БД не удаляются)?" "n"; then
|
docker compose "${PROFILE_L2[@]}" down
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" down
|
docker compose down
|
||||||
info "Контейнеры остановлены. Данные БД в томе postgres_data сохранены."
|
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Удалить том БД (down -v)? ОПАСНО." "n"; then
|
||||||
if ask_yes_no "Удалить том с данными PostgreSQL (docker compose down -v)? ОПАСНО: потеря БД." "n"; then
|
if ask_yes_no "Точно удалить?" "n"; then
|
||||||
warn "Будет выполнено: docker compose --profile placeholder down -v"
|
docker compose "${PROFILE_L2[@]}" down -v
|
||||||
if ask_yes_no "Точно удалить тома?" "n"; then
|
docker compose down -v
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" down -v
|
|
||||||
info "Тома удалены."
|
|
||||||
else
|
|
||||||
info "Отмена удаления томов."
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Шаг 3: запуск ---
|
|
||||||
step_header "Шаг 3 — Запуск"
|
step_header "Шаг 3 — Запуск"
|
||||||
if ask_yes_no "Запустить / обновить PostgreSQL (up -d postgres)?" "n"; then
|
if ask_yes_no "Запустить PostgreSQL?" "n"; then
|
||||||
docker compose up -d postgres
|
docker compose up -d postgres
|
||||||
info "Ожидание pg_isready..."
|
|
||||||
EV_USER="$(read_env_val POSTGRES_USER)"
|
EV_USER="$(read_env_val POSTGRES_USER)"
|
||||||
EV_DB="$(read_env_val POSTGRES_DB)"
|
EV_DB="$(read_env_val POSTGRES_DB)"
|
||||||
for _ in $(seq 1 60); do
|
for _ in $(seq 1 60); do
|
||||||
if docker compose exec -T postgres pg_isready -U "$EV_USER" -d "$EV_DB" >/dev/null 2>&1; then
|
docker compose exec -T postgres pg_isready -U "$EV_USER" -d "$EV_DB" >/dev/null 2>&1 && break
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Запустить login + game (profile l2)?" "n"; then
|
||||||
if ask_yes_no "Запустить l2-server (placeholder, нужен здоровый PostgreSQL)?" "n"; then
|
if postgres_running; then
|
||||||
if ! postgres_running; then
|
docker compose "${PROFILE_L2[@]}" up -d login game
|
||||||
warn "PostgreSQL не запущен. Сначала поднимите postgres."
|
|
||||||
else
|
else
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" up -d l2-server
|
warn "Сначала поднимите postgres."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Шаг 4: перезапуск ---
|
|
||||||
step_header "Шаг 4 — Перезапуск"
|
step_header "Шаг 4 — Перезапуск"
|
||||||
if ask_yes_no "Перезапустить PostgreSQL (restart postgres)?" "n"; then
|
if ask_yes_no "Перезапустить PostgreSQL?" "n"; then
|
||||||
if postgres_running; then
|
if postgres_running; then
|
||||||
docker compose restart postgres
|
docker compose restart postgres
|
||||||
info "PostgreSQL перезапущен."
|
|
||||||
else
|
else
|
||||||
warn "PostgreSQL не в состоянии running. Выполняю up -d postgres."
|
|
||||||
docker compose up -d postgres
|
docker compose up -d postgres
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Перезапустить login?" "n"; then
|
||||||
if ask_yes_no "Перезапустить l2-server (restart l2-server)?" "n"; then
|
login_running && docker compose "${PROFILE_L2[@]}" restart login || warn "login не запущен."
|
||||||
if l2_running; then
|
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" restart l2-server
|
|
||||||
info "l2-server перезапущен."
|
|
||||||
else
|
|
||||||
warn "l2-server не запущен. Пропуск."
|
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Перезапустить game?" "n"; then
|
||||||
|
game_running && docker compose "${PROFILE_L2[@]}" restart game || warn "game не запущен."
|
||||||
fi
|
fi
|
||||||
|
if ask_yes_no "Полный перезапуск: down → postgres → login → game?" "n"; then
|
||||||
if ask_yes_no "Перезапустить весь стек: сначала down, затем up postgres (+ опционально l2)?" "n"; then
|
docker compose "${PROFILE_L2[@]}" down
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" down
|
docker compose down
|
||||||
docker compose up -d postgres
|
docker compose up -d postgres
|
||||||
EV_USER="$(read_env_val POSTGRES_USER)"
|
sleep 3
|
||||||
EV_DB="$(read_env_val POSTGRES_DB)"
|
docker compose "${PROFILE_L2[@]}" up -d login game
|
||||||
for _ in $(seq 1 60); do
|
|
||||||
if docker compose exec -T postgres pg_isready -U "$EV_USER" -d "$EV_DB" >/dev/null 2>&1; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
if ask_yes_no "Сразу поднять l2-server (placeholder)?" "n"; then
|
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" up -d l2-server
|
|
||||||
fi
|
|
||||||
info "Стек перезапущен."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Итог ---
|
|
||||||
step_header "Готово"
|
step_header "Готово"
|
||||||
if ask_yes_no "Показать итоговый статус?" "y"; then
|
if ask_yes_no "Показать статус?" "y"; then
|
||||||
docker compose "${PROFILE_PLACEHOLDER[@]}" ps -a || true
|
docker compose ps -a
|
||||||
|
docker compose "${PROFILE_L2[@]}" ps -a 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
info "Логи: docker compose logs -f login game postgres"
|
||||||
info "Логи: docker compose logs -f postgres"
|
|
||||||
info "Выход из проекта без удаления томов: docker compose --profile placeholder down"
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Применить SQL к уже существующей БД (если том postgres не пересоздавали).
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
cd "$ROOT"
|
||||||
|
ENV_FILE="${ROOT}/.env"
|
||||||
|
[[ -f "$ENV_FILE" ]] || { echo "Нет .env — сначала ./install.sh"; exit 1; }
|
||||||
|
read_env() { grep -m1 "^${1}=" "$ENV_FILE" | sed "s/^${1}=//"; }
|
||||||
|
U="$(read_env POSTGRES_USER)"
|
||||||
|
DB="$(read_env POSTGRES_DB)"
|
||||||
|
export PGPASSWORD="$(read_env POSTGRES_PASSWORD)"
|
||||||
|
for f in "$ROOT"/docker/initdb/0*.sql; do
|
||||||
|
echo "==> $(basename "$f")"
|
||||||
|
docker compose exec -T postgres psql -v ON_ERROR_STOP=1 -U "$U" -d "$DB" -f - <"$f"
|
||||||
|
done
|
||||||
|
echo "Готово."
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Подставить POSTGRES_* из .env в config/login и config/game (без коммита .env).
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
ENV_FILE="${ROOT}/.env"
|
||||||
|
[[ -f "$ENV_FILE" ]] || { echo "Нет .env"; exit 1; }
|
||||||
|
read_env() { grep -m1 "^${1}=" "$ENV_FILE" | sed "s/^${1}=//"; }
|
||||||
|
U="$(read_env POSTGRES_USER)"
|
||||||
|
P="$(read_env POSTGRES_PASSWORD)"
|
||||||
|
DB="$(read_env POSTGRES_DB)"
|
||||||
|
for f in "$ROOT/config/login/LoginServer.properties" "$ROOT/config/game/Server.properties"; do
|
||||||
|
[[ -f "$f" ]] || continue
|
||||||
|
sed -i "s|^Login = .*|Login = $U|" "$f"
|
||||||
|
sed -i "s|^Password = .*|Password = $P|" "$f"
|
||||||
|
sed -i "s|jdbc:postgresql://postgres:5432/[^?]*|jdbc:postgresql://postgres:5432/$DB|" "$f"
|
||||||
|
echo "Обновлён: $f"
|
||||||
|
done
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
a1b2c3d4e5f6789012345678901234ef
|
||||||
Reference in New Issue
Block a user