Logging für REST Abfragen aus dem Palworld Server etnfernt
All checks were successful
Deploy GSM / deploy (push) Successful in 24s

This commit is contained in:
2026-01-12 03:07:23 +01:00
parent 4bfb870fbb
commit 51b95240f2
4 changed files with 39 additions and 15 deletions

View File

@@ -9,7 +9,10 @@
"Bash(cat:*)", "Bash(cat:*)",
"Bash(git add:*)", "Bash(git add:*)",
"Bash(dir:*)", "Bash(dir:*)",
"Bash(ssh-keygen:*)" "Bash(ssh-keygen:*)",
"WebSearch",
"WebFetch(domain:tech.palworldgame.com)",
"WebFetch(domain:docs.palworldgame.com)"
] ]
} }
} }

View File

@@ -0,0 +1,5 @@
; This configuration file is a sample of the default server settings.
; Changes to this file will NOT be reflected on the server.
; To change the server settings, modify Pal/Saved/Config/LinuxServer/PalWorldSettings.ini.
[/Script/Pal.PalGameWorldSettings]
OptionSettings=(Difficulty=None,RandomizerType=None,RandomizerSeed="",bIsRandomizerPalLevelRandom=False,DayTimeSpeedRate=1.000000,NightTimeSpeedRate=1.000000,ExpRate=1.000000,PalCaptureRate=1.000000,PalSpawnNumRate=1.000000,PalDamageRateAttack=1.000000,PalDamageRateDefense=1.000000,PlayerDamageRateAttack=1.000000,PlayerDamageRateDefense=1.000000,PlayerStomachDecreaceRate=1.000000,PlayerStaminaDecreaceRate=1.000000,PlayerAutoHPRegeneRate=1.000000,PlayerAutoHpRegeneRateInSleep=1.000000,PalStomachDecreaceRate=1.000000,PalStaminaDecreaceRate=1.000000,PalAutoHPRegeneRate=1.000000,PalAutoHpRegeneRateInSleep=1.000000,BuildObjectHpRate=1.000000,BuildObjectDamageRate=1.000000,BuildObjectDeteriorationDamageRate=1.000000,CollectionDropRate=1.000000,CollectionObjectHpRate=1.000000,CollectionObjectRespawnSpeedRate=1.000000,EnemyDropItemRate=1.000000,DeathPenalty=All,bEnablePlayerToPlayerDamage=False,bEnableFriendlyFire=False,bEnableInvaderEnemy=True,bActiveUNKO=False,bEnableAimAssistPad=True,bEnableAimAssistKeyboard=False,DropItemMaxNum=3000,DropItemMaxNum_UNKO=100,BaseCampMaxNum=128,BaseCampWorkerMaxNum=15,DropItemAliveMaxHours=1.000000,bAutoResetGuildNoOnlinePlayers=False,AutoResetGuildTimeNoOnlinePlayers=72.000000,GuildPlayerMaxNum=20,BaseCampMaxNumInGuild=4,PalEggDefaultHatchingTime=72.000000,WorkSpeedRate=1.000000,AutoSaveSpan=30.000000,bIsMultiplay=False,bIsPvP=False,bHardcore=False,bPalLost=False,bCharacterRecreateInHardcore=False,bCanPickupOtherGuildDeathPenaltyDrop=False,bEnableNonLoginPenalty=True,bEnableFastTravel=True,bEnableFastTravelOnlyBaseCamp=False,bIsStartLocationSelectByMap=True,bExistPlayerAfterLogout=False,bEnableDefenseOtherGuildPlayer=False,bInvisibleOtherGuildBaseCampAreaFX=False,bBuildAreaLimit=False,ItemWeightRate=1.000000,CoopPlayerMaxNum=4,ServerPlayerMaxNum=32,ServerName="Default Palworld Server",ServerDescription="",AdminPassword="gsm-pal-admin-2026",ServerPassword="",bAllowClientMod=True,PublicPort=8211,PublicIP="",RCONEnabled=True,RCONPort=25575,Region="",bUseAuth=False,BanListURL="https://api.palworldgame.com/api/banlist.txt",RESTAPIEnabled=True,RESTAPIPort=8212,bShowPlayerList=False,ChatPostLimitPerMinute=30,CrossplayPlatforms=(Steam,Xbox,PS5,Mac),bIsUseBackupSaveData=True,LogFormatType=Text,bIsShowJoinLeftMessage=True,SupplyDropSpan=180,EnablePredatorBossPal=True,MaxBuildingLimitNum=0,ServerReplicatePawnCullDistance=15000.000000,bAllowGlobalPalboxExport=True,bAllowGlobalPalboxImport=False,EquipmentDurabilityDamageRate=1.000000,ItemContainerForceMarkDirtyInterval=1.000000,ItemCorruptionMultiplier=1.000000,DenyTechnologyList=,GuildRejoinCooldownMinutes=0,BlockRespawnTime=5.000000,RespawnPenaltyDurationThreshold=0.000000,RespawnPenaltyTimeScale=2.000000,bDisplayPvPItemNumOnWorldMap_BaseCamp=False,bDisplayPvPItemNumOnWorldMap_Player=False,AdditionalDropItemWhenPlayerKillingInPvPMode="PlayerDropItem",AdditionalDropItemNumWhenPlayerKillingInPvPMode=1,bAdditionalDropItemWhenPlayerKillingInPvPMode=False,bAllowEnhanceStat_Health=True,bAllowEnhanceStat_Attack=True,bAllowEnhanceStat_Stamina=True,bAllowEnhanceStat_Weight=True,bAllowEnhanceStat_WorkSpeed=True)

View File

@@ -4,6 +4,24 @@ const rconConnections = new Map();
const playerCache = new Map(); const playerCache = new Map();
const CACHE_TTL = 30000; // 30 seconds const CACHE_TTL = 30000; // 30 seconds
// Palworld REST API helper
async function getPalworldPlayers(server) {
const port = server.restApiPort || 8212;
const url = `http://${server.host}:${port}/v1/api/players`;
const auth = Buffer.from(`admin:${server.rconPassword}`).toString('base64');
const response = await fetch(url, {
headers: { 'Authorization': `Basic ${auth}` },
signal: AbortSignal.timeout(5000)
});
if (!response.ok) {
throw new Error(`REST API error: ${response.status}`);
}
return await response.json();
}
async function getConnection(server) { async function getConnection(server) {
const key = `${server.host}:${server.rconPort}`; const key = `${server.host}:${server.rconPort}`;
@@ -88,10 +106,9 @@ export async function getPlayers(server) {
const lines = response.split('\n').filter(l => l.trim() && !l.includes('listusers')); const lines = response.split('\n').filter(l => l.trim() && !l.includes('listusers'));
result = { online: lines.length, max: null }; result = { online: lines.length, max: null };
} else if (server.type === 'palworld') { } else if (server.type === 'palworld') {
const response = await sendRconCommand(server, 'ShowPlayers'); // Use REST API instead of RCON for Palworld
// Format: "name,playeruid,steamid\nPlayer1,123,765...\nPlayer2,456,765..." const data = await getPalworldPlayers(server);
const lines = response.split('\n').filter(l => l.trim() && !l.toLowerCase().startsWith('name,')); result = { online: data.players?.length || 0, max: null };
result = { online: lines.length, max: null };
} }
playerCache.set(cacheKey, { data: result, time: Date.now() }); playerCache.set(cacheKey, { data: result, time: Date.now() });
@@ -151,15 +168,9 @@ export async function getPlayerList(server) {
const lines = response.split('\n').filter(l => l.trim() && !l.includes('listusers')); const lines = response.split('\n').filter(l => l.trim() && !l.includes('listusers'));
players = lines.map(l => l.trim()).filter(p => p); players = lines.map(l => l.trim()).filter(p => p);
} else if (server.type === 'palworld') { } else if (server.type === 'palworld') {
const response = await sendRconCommand(server, 'ShowPlayers'); // Use REST API instead of RCON for Palworld
// Format: "name,playeruid,steamid\nPlayer1,123,765...\nPlayer2,456,765..." const data = await getPalworldPlayers(server);
const lines = response.split('\n').filter(l => l.trim() && !l.toLowerCase().startsWith('name,')); players = (data.players || []).map(p => p.name);
for (const line of lines) {
const parts = line.split(',');
if (parts.length >= 1 && parts[0].trim()) {
players.push(parts[0].trim());
}
}
} }
const result = { players }; const result = { players };

View File

@@ -192,7 +192,12 @@ export async function getConsoleLog(server, lines = 50) {
const result = await ssh.execCommand(`/usr/local/bin/docker-logs-tz ${server.containerName} ${lines}`); const result = await ssh.execCommand(`/usr/local/bin/docker-logs-tz ${server.containerName} ${lines}`);
return result.stdout || result.stderr; return result.stdout || result.stderr;
} else if (server.runtime === 'systemd') { } else if (server.runtime === 'systemd') {
const result = await ssh.execCommand(`tail -n ${lines} ${server.workDir}/logs/VRisingServer.log 2>/dev/null || journalctl -u ${server.serviceName} -n ${lines} --no-pager`); let cmd = `tail -n ${lines} ${server.workDir}/logs/VRisingServer.log 2>/dev/null || journalctl -u ${server.serviceName} -n ${lines} --no-pager`;
// Filter out REST API spam for Palworld
if (server.type === 'palworld') {
cmd = `journalctl -u ${server.serviceName} -n ${lines * 2} --no-pager | grep -v "REST accessed endpoint" | tail -n ${lines}`;
}
const result = await ssh.execCommand(cmd);
return result.stdout || result.stderr; return result.stdout || result.stderr;
} else if (server.runtime === 'pm2') { } else if (server.runtime === 'pm2') {
const nvmPrefix = "source ~/.nvm/nvm.sh && "; const nvmPrefix = "source ~/.nvm/nvm.sh && ";