Add panel feature updates across API, daemon, and web
This commit is contained in:
@@ -22,6 +22,34 @@
|
||||
"when": 1772300000000,
|
||||
"tag": "0002_cs2_add_metamod_workflow",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1772400000000,
|
||||
"tag": "0003_global_plugin_registry",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1772600000000,
|
||||
"tag": "0004_cs2_startup_parameters",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1772800000000,
|
||||
"tag": "0005_cs2_servername_default",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1772900000000,
|
||||
"tag": "0006_cs2_servername_branding",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from './backups';
|
||||
export * from './plugins';
|
||||
export * from './schedules';
|
||||
export * from './audit-logs';
|
||||
export * from './server-databases';
|
||||
|
||||
@@ -6,11 +6,17 @@ import {
|
||||
boolean,
|
||||
timestamp,
|
||||
pgEnum,
|
||||
jsonb,
|
||||
bigint,
|
||||
} from 'drizzle-orm/pg-core';
|
||||
import { games } from './games';
|
||||
import { servers } from './servers';
|
||||
import { users } from './users';
|
||||
|
||||
export const pluginSourceEnum = pgEnum('plugin_source', ['spiget', 'manual']);
|
||||
export const pluginReleaseChannelEnum = pgEnum('plugin_release_channel', ['stable', 'beta', 'alpha']);
|
||||
export const pluginReleaseArtifactTypeEnum = pgEnum('plugin_release_artifact_type', ['file', 'zip']);
|
||||
export const pluginInstallStatusEnum = pgEnum('plugin_install_status', ['installed', 'updating', 'failed']);
|
||||
|
||||
export const plugins = pgTable('plugins', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
@@ -24,6 +30,29 @@ export const plugins = pgTable('plugins', {
|
||||
externalId: varchar('external_id', { length: 255 }),
|
||||
downloadUrl: text('download_url'),
|
||||
version: varchar('version', { length: 100 }),
|
||||
isGlobal: boolean('is_global').default(true).notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const pluginReleases = pgTable('plugin_releases', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
pluginId: uuid('plugin_id')
|
||||
.notNull()
|
||||
.references(() => plugins.id, { onDelete: 'cascade' }),
|
||||
version: varchar('version', { length: 100 }).notNull(),
|
||||
channel: pluginReleaseChannelEnum('channel').default('stable').notNull(),
|
||||
artifactType: pluginReleaseArtifactTypeEnum('artifact_type').default('file').notNull(),
|
||||
artifactUrl: text('artifact_url').notNull(),
|
||||
destination: text('destination'),
|
||||
fileName: varchar('file_name', { length: 255 }),
|
||||
checksumSha256: varchar('checksum_sha256', { length: 128 }),
|
||||
sizeBytes: bigint('size_bytes', { mode: 'number' }),
|
||||
changelog: text('changelog'),
|
||||
installSchema: jsonb('install_schema').default([]).notNull(),
|
||||
configTemplates: jsonb('config_templates').default([]).notNull(),
|
||||
isPublished: boolean('is_published').default(true).notNull(),
|
||||
createdByUserId: uuid('created_by_user_id').references(() => users.id, { onDelete: 'set null' }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
});
|
||||
@@ -36,7 +65,24 @@ export const serverPlugins = pgTable('server_plugins', {
|
||||
pluginId: uuid('plugin_id')
|
||||
.notNull()
|
||||
.references(() => plugins.id, { onDelete: 'cascade' }),
|
||||
releaseId: uuid('release_id').references(() => pluginReleases.id, { onDelete: 'set null' }),
|
||||
installedVersion: varchar('installed_version', { length: 100 }),
|
||||
isActive: boolean('is_active').default(true).notNull(),
|
||||
installOptions: jsonb('install_options').default({}).notNull(),
|
||||
autoUpdateChannel: pluginReleaseChannelEnum('auto_update_channel').default('stable').notNull(),
|
||||
isPinned: boolean('is_pinned').default(false).notNull(),
|
||||
status: pluginInstallStatusEnum('status').default('installed').notNull(),
|
||||
lastError: text('last_error'),
|
||||
installedAt: timestamp('installed_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const serverPluginFiles = pgTable('server_plugin_files', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
serverPluginId: uuid('server_plugin_id')
|
||||
.notNull()
|
||||
.references(() => serverPlugins.id, { onDelete: 'cascade' }),
|
||||
path: text('path').notNull(),
|
||||
kind: varchar('kind', { length: 32 }).default('artifact').notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
pgTable,
|
||||
uuid,
|
||||
varchar,
|
||||
text,
|
||||
integer,
|
||||
timestamp,
|
||||
} from 'drizzle-orm/pg-core';
|
||||
import { servers } from './servers';
|
||||
|
||||
export const serverDatabases = pgTable('server_databases', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
serverId: uuid('server_id')
|
||||
.notNull()
|
||||
.references(() => servers.id, { onDelete: 'cascade' }),
|
||||
name: varchar('name', { length: 255 }).notNull(),
|
||||
databaseName: varchar('database_name', { length: 255 }).notNull().unique(),
|
||||
username: varchar('username', { length: 64 }).notNull().unique(),
|
||||
password: text('password').notNull(),
|
||||
host: varchar('host', { length: 255 }).notNull(),
|
||||
port: integer('port').notNull(),
|
||||
phpMyAdminUrl: text('phpmyadmin_url'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
});
|
||||
@@ -2,6 +2,57 @@ import { createDb } from './client';
|
||||
import { games } from './schema/games';
|
||||
import { users } from './schema/users';
|
||||
|
||||
const DEFAULT_CS2_SERVER_CFG = `// ============================================
|
||||
// CS2 Server Config
|
||||
// ============================================
|
||||
|
||||
// ---- Sunucu Bilgileri ----
|
||||
hostname "SourceGamePanel CS2 Server"
|
||||
sv_password ""
|
||||
rcon_password "changeme"
|
||||
sv_cheats 0
|
||||
|
||||
// ---- Topluluk Sunucu Gorunurlugu ----
|
||||
sv_region 3
|
||||
sv_tags "competitive,community"
|
||||
sv_lan 0
|
||||
sv_steamgroup ""
|
||||
sv_steamgroup_exclusive 0
|
||||
|
||||
// ---- Performans ----
|
||||
sv_maxrate 0
|
||||
sv_minrate 64000
|
||||
sv_max_queries_sec 5
|
||||
sv_max_queries_window 30
|
||||
sv_parallel_sendsnapshot 1
|
||||
net_maxroutable 1200
|
||||
|
||||
// ---- Baglanti ----
|
||||
sv_maxclients 16
|
||||
sv_timeout 60
|
||||
|
||||
// ---- GOTV (Tamamen Kapali) ----
|
||||
tv_enable 0
|
||||
tv_autorecord 0
|
||||
tv_delay 0
|
||||
tv_maxclients 0
|
||||
tv_port 0
|
||||
|
||||
// ---- Loglama ----
|
||||
log on
|
||||
mp_logmoney 0
|
||||
mp_logdetail 0
|
||||
mp_logdetail_items 0
|
||||
sv_logfile 1
|
||||
|
||||
// ---- Genel Oyun Ayarlari ----
|
||||
mp_autokick 0
|
||||
sv_allow_votes 0
|
||||
sv_alltalk 0
|
||||
sv_deadtalk 1
|
||||
sv_voiceenable 1
|
||||
`;
|
||||
|
||||
async function seed() {
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
if (!databaseUrl) {
|
||||
@@ -101,9 +152,33 @@ async function seed() {
|
||||
parser: 'keyvalue',
|
||||
editableKeys: [
|
||||
'hostname',
|
||||
'sv_tags',
|
||||
'sv_password',
|
||||
'rcon_password',
|
||||
'sv_cheats',
|
||||
'sv_region',
|
||||
'sv_lan',
|
||||
'sv_steamgroup',
|
||||
'sv_steamgroup_exclusive',
|
||||
'sv_maxrate',
|
||||
'sv_minrate',
|
||||
'sv_max_queries_sec',
|
||||
'sv_max_queries_window',
|
||||
'sv_parallel_sendsnapshot',
|
||||
'net_maxroutable',
|
||||
'sv_maxclients',
|
||||
'sv_timeout',
|
||||
'tv_enable',
|
||||
'tv_autorecord',
|
||||
'tv_delay',
|
||||
'tv_maxclients',
|
||||
'tv_port',
|
||||
'sv_logfile',
|
||||
'mp_autokick',
|
||||
'sv_allow_votes',
|
||||
'sv_alltalk',
|
||||
'sv_deadtalk',
|
||||
'sv_voiceenable',
|
||||
'mp_autoteambalance',
|
||||
'mp_limitteams',
|
||||
],
|
||||
@@ -111,6 +186,27 @@ async function seed() {
|
||||
{ path: 'game/csgo/cfg/autoexec.cfg', parser: 'keyvalue' },
|
||||
],
|
||||
automationRules: [
|
||||
{
|
||||
id: 'cs2-write-default-server-config',
|
||||
event: 'server.install.completed',
|
||||
enabled: true,
|
||||
runOncePerServer: true,
|
||||
continueOnError: false,
|
||||
actions: [
|
||||
{
|
||||
id: 'write-cs2-default-server-config',
|
||||
type: 'write_file',
|
||||
path: '/game/csgo/cfg/server.cfg',
|
||||
data: DEFAULT_CS2_SERVER_CFG,
|
||||
},
|
||||
{
|
||||
id: 'write-cs2-persisted-server-config',
|
||||
type: 'write_file',
|
||||
path: '/game/csgo/cfg/.sourcegamepanel-server.cfg',
|
||||
data: DEFAULT_CS2_SERVER_CFG,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'cs2-install-latest-metamod',
|
||||
event: 'server.install.completed',
|
||||
@@ -168,7 +264,12 @@ async function seed() {
|
||||
description: 'Steam Game Server Login Token (optional for local testing)',
|
||||
required: false,
|
||||
},
|
||||
{ key: 'CS2_SERVERNAME', default: 'GamePanel CS2 Server', description: 'Server name', required: false },
|
||||
{
|
||||
key: 'CS2_SERVERNAME',
|
||||
default: 'SourceGamePanel CS2 Server',
|
||||
description: 'Server name',
|
||||
required: false,
|
||||
},
|
||||
{ key: 'CS2_PORT', default: '27015', description: 'Game port', required: false },
|
||||
{ key: 'CS2_STARTMAP', default: 'de_dust2', description: 'Initial map', required: false },
|
||||
{ key: 'CS2_MAXPLAYERS', default: '16', description: 'Max players', required: false },
|
||||
@@ -179,6 +280,38 @@ async function seed() {
|
||||
description: 'Bind address',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: 'CS2_HOST_WORKSHOP_COLLECTION',
|
||||
default: '',
|
||||
description: 'Steam Workshop collection id to load',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: 'CS2_HOST_WORKSHOP_MAP',
|
||||
default: '',
|
||||
description: 'Steam Workshop map id to launch',
|
||||
required: false,
|
||||
},
|
||||
{ key: 'CS2_GAMETYPE', default: '0', description: 'Game type numeric value', required: false },
|
||||
{ key: 'CS2_GAMEMODE', default: '1', description: 'Game mode numeric value', required: false },
|
||||
{
|
||||
key: 'CS2_ADDITIONAL_ARGS',
|
||||
default: '',
|
||||
description: 'Extra startup arguments appended to the server launch command',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: 'CS2_INSECURE',
|
||||
label: 'Insecure Mode',
|
||||
default: '',
|
||||
description: 'Toggles the -insecure launch flag inside CS2_ADDITIONAL_ARGS',
|
||||
required: false,
|
||||
inputType: 'boolean',
|
||||
composeInto: 'CS2_ADDITIONAL_ARGS',
|
||||
flagValue: '-insecure',
|
||||
enabledLabel: 'Aktif',
|
||||
disabledLabel: 'Pasif',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user