HeyLeute,
ich habe mir einen DayZ Server auf Linux aufgesetzt und diesen lasse ich nun alle 6 Stunden via Cron neu starten. Allerdings wird der Server nicht einmal sondern mehrfach neu gestartet. Woran das liegt weiß ich leidernicht. Wenn ich die Datei, die Cron automatisch ausführen soll, manuell ausführe passiert genau das was er machen soll. Er startet EINMAL neu + Löscht die Log Dateien + Räumt meine Datenbank auf + Speichert Spielerprofile in meinem Cache
Hier mal mein Cronjob (Server soll sich um 0,6,12,18 Uhr neustarten):
in der Datei restart.sh steht nun folgendes:
Was die Dateien machen erklärt sich ja eigentlich von selbst. cleanup_sql.pl räumt meine Datenbank auf und entfernt alle unützen Einträge. Die dellog.sh Datei entfernt alle Einträge aus den Log Dateien da einige nach nur wenigen Minuten sehr groß werden, habe ich das so eingerichtet. Leider kann man bei DayZ und vor allem bei Battleye kein Loglevel einstellen darum diese Lösung. Die restarter.pl ist die eigentliche "restart"-Datei. Sie speichert den cache der Spieler richtig ab und startet den Server neu. Welche Datei das Problem verursacht oder ob es wirklich nur am Cronjob liegt kann ich leider nicht sagen da brauch ich euch. Nur um alles zu zeigen hier mal noch die anderen Dateien:
cleanup_sql.pl:
#!/usr/bin/perl
#
use DBI;
use warnings;
use strict;
use constant {
INSTANCE => 11, # Chernarus instance
DB_NAME => 'DBName', # Set database name
DB_LOGIN => 'UserName', # Set database login
DB_PASSWD => 'DBPass', # Set database password
DB_HOST => 'localhost', # Set database host
DB_PORT => 3306, # Set database port (default 3306)
};
my $dbh = connect_to_db();
clean_player_login_data();
clean_character_data();
clean_old_character_player_data();
clean_character_player_never_logged_in_data();
update_trader_stock();
#clean_objects_empty();
clean_destroyed_objects();
clean_objects_old();
unlock_non_key_vehicles();
$dbh->disconnect;
exit;
#---------------------------------------------------------------------------
# SQL Query Sub-functions
#
sub connect_to_db {
my $dbh = DBI->connect('dbi:mysql:'.DB_NAME.':'.DB_HOST.':'.DB_PORT, DB_LOGIN, DB_PASSWD,
{'PrintError' => 1, 'RaiseError' => 1, 'AutoCommit' => 1})
or die "Can't connect to mysql: $!";
$dbh->{'mysql_auto_reconnect'} = 1;
return $dbh;
}
# Clean player_login data older than 2 days
sub clean_player_login_data {
my $sql = "DELETE FROM `Player_LOGIN` WHERE `Datestamp` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 2 DAY);";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
# Clean character data (delete all Alive=0 and only if 1 row with Alive=1 exists). Humanity is kept from old Alive=0 entry.
sub clean_character_data {
my $sql = "DELETE from Character_DATA
USING Character_DATA, Character_DATA as tempchartable
WHERE (Character_DATA.PlayerUID = tempchartable.PlayerUID)
AND (NOT Character_DATA.alive = tempchartable.alive)
AND (Character_DATA.alive = 0)";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
# Delete from Character_Data and Player_DATA table - characters not played more than 21 days (not playing anymore?):
sub clean_old_character_player_data {
my $sql = "DELETE FROM Character_DATA, Player_DATA USING Character_DATA, Player_DATA
WHERE Character_DATA.LastLogin < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 21 DAY)
AND Character_DATA.PlayerUID = Player_DATA.PlayerUID;";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
# Delete from Character_Data, Player_Data where worldspace / Medical is empty and last login was more than 2 days ago
sub clean_character_player_never_logged_in_data {
my $sql = "DELETE FROM Character_DATA, Player_DATA USING Character_DATA, Player_DATA
WHERE Character_DATA.LastLogin < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 2 DAY)
AND Worldspace = '[]'
AND Medical = '[]'
AND Character_DATA.PlayerUID = Player_DATA.PlayerUID;";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
sub update_trader_stock {
my $sql = "UPDATE `Traders_DATA` SET qty=10 WHERE qty=0 AND afile<>'trade_any_vehicle' AND afile<>'trade_any_boat';";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
#sub clean_objects_empty {
# my $sql = "DELETE FROM `Object_DATA`
# WHERE `last_updated` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY)
# AND `Datestamp` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY)
# AND ( (`Inventory` IS NULL) OR (`Inventory` = '[]') OR (`Inventory` = '[[[],[]],[[],[]],[[],[]]]') )";
# original
#DELETE FROM `Object_DATA`
#WHERE `LastUpdated` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 14 DAY)
#AND `Datestamp` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 24 DAY)
#AND ( (`Inventory` IS NULL) OR (`Inventory` = '[]') OR (`Inventory` = '[[[],[]],[[],[]],[[],[]]]') )
# my $sth = $dbh->prepare ($sql);
# my $res = $sth->execute ();
# $sth->finish;
# return $res;
#}
# Delete destroyed onjects (where damage=1) (original event)
sub clean_destroyed_objects {
my $sql = "DELETE FROM `Object_DATA` WHERE Damage = 1;";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
# Delete old objects: last updated more than 24 days ago, Datestamp more than 42 days ago (original event)
sub clean_objects_old {
my $sql = "DELETE FROM `Object_DATA`
WHERE `last_updated` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 24 DAY)
AND `Datestamp` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 42 DAY);";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
# Unlock all non-key vehicles (uses function FindVehicleKeysCount on table Object_DATA from original epoch events in Github!)
sub unlock_non_key_vehicles {
my $sql = "
UPDATE
`Object_DATA`
SET
`Object_DATA`.`CharacterID` = 0
WHERE
`Object_DATA`.`CharacterID` <> 0
AND `Object_DATA`.`CharacterID` <= 12500
AND `Object_DATA`.`Classname` NOT LIKE 'Tent%'
AND `Object_DATA`.`Classname` NOT LIKE '%Locked'
AND `Object_DATA`.`Classname` NOT LIKE 'Land%'
AND `Object_DATA`.`Classname` NOT LIKE 'Cinder%'
AND `Object_DATA`.`Classname` NOT LIKE 'Wood%'
AND `Object_DATA`.`Classname` NOT LIKE 'Metal%'
AND `Object_DATA`.`Classname` NOT LIKE '%Storage%'
AND `Object_DATA`.`Classname` NOT IN ('OutHouse_DZ', 'GunRack_DZ', 'WorkBench_DZ', 'Sandbag1_DZ', 'FireBarrel_DZ', 'DesertCamoNet_DZ', 'StickFence_DZ', 'LightPole_DZ', 'DeerStand_DZ', 'ForestLargeCamoNet_DZ', 'DesertLargeCamoNet_DZ', 'Plastic_Pole_EP1_DZ', 'Hedgehog_DZ', 'FuelPump_DZ', 'Fort_RazorWire', 'SandNest_DZ', 'ForestCamoNet_DZ', 'Fence_corrugated_DZ', 'CanvasHut_DZ', 'Generator_DZ', 'BagFenceRound_DZ')
AND FindVehicleKeysCount(Object_DATA.CharacterID) = 0
";
my $sth = $dbh->prepare ($sql);
my $res = $sth->execute ();
$sth->finish;
return $res;
}
Alles anzeigen
restarter.pl:
#!/usr/bin/perl
use warnings;
use strict;
use constant PORT => 2302; # Change it with epoch.sh
use constant PATH => $ENV{'PWD'}.'/'; # Set your epoch server dir
use constant PIDFILE => PATH.PORT.'.pid';
use constant CACHE_DIR => PATH.'cache/players';
unless (-f PATH.'server') {
print STDERR "Can't found server binary!\n";
exit;
}
set_time ();
logrotate ();
if (-f PIDFILE) {
open (IN, '<'.PIDFILE) or die "Can't open: $!";
my $pid = int(<IN>);
close (IN);
my $res = `kill -TERM $pid 2>&1`;
print STDERR $res,"\n" if $res;
unlink (PIDFILE) if (-f PIDFILE);
backup_cache();
}
print STDERR "Restart Dayz Epoch server...\n";
chdir (PATH);
my $cmd = '/usr/bin/screen -h 20000 -fa -d -m -S epoch '.PATH.'epoch.sh';
my $res = `$cmd`;
print STDERR $res,"\n" if $res;
exit;
#-----------------------------------------------------------------------------------------------
sub set_time {
my ($s, $m, $h, $day, $mon, $y) = localtime(time() - 3*3600);
$y += 1900;
$mon++;
# Uncomment to disabe night
#($h, $m) = (17, 0) if ($h > 17 || ($h >= 0 && $h < 4));
my $file = PATH.'cache/set_time.sqf';
open (IN, ">$file") or die "Can't find $file";
# ["PASS", [year, month, day, hour, minute]]
print IN '["PASS",[2012,6,6,'.$h.','.$m.']]'; # with full moon
close (IN);
}
sub logrotate {
my $log = PATH.'dump.log';
if (-f $log) {
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat($log);
if ($size && $size >= 100000000) {
print STDERR "logrotate $size\n";
my $nlog = $log.'.'.time();
my $res = `cp $log $nlog 2>&1`;
print STDERR $res,"\n" if $res;
$res = `echo '' > $log 2>&1`;
print STDERR $res,"\n" if $res;
}
}
}
sub backup_cache {
return unless (-d CACHE_DIR);
opendir (DIR, CACHE_DIR) or die $!;
while (my $file = readdir (DIR)) {
next unless ($file =~ m/^\d+$/ && $file ne '1');
my $dir = CACHE_DIR.'/'.$file;
my $backup = CACHE_DIR.'/1';
next unless (-d $dir);
my $res = `mv -f $dir $backup 2>&1`;
print STDERR $res,"\n" if $res;
}
closedir (DIR);
}
Alles anzeigen
dellog.sh:
#!/bin/bash
cd /home/run/epochserver/
> dump.log
> server.log
cd /home/run/epochserver/expansion/battleye/
> addbackpackcargo.log
> addmagazinecargo.log
> attachto.log
> createvehicle.log
> deletevehicle.log
> mpeventhandler.log
> publicvariable.log
> scripts.log
> selectplayer.log
> setdamage.log
> setvariable.log
Alles anzeigen
Kann mir irgendjemand sagen warum beim manuellen ausführen von "restart.sh" der Server genau so restartet wird wie es sein soll und bei einem automatischen Restart wird er ca eine Stunde lang ständig an und abgeschalten? (So war es zumindest heute Früh mit dem 6Uhr restart. Ab 7 Uhr lief dann der Server wieder bis zum 12Uhr restart und nun geht es gerade wieder von vorne los )
Danke schonmal für eure Hilfe
Edit:
Übrigens:
Zuerst dachte ich der Server stürzt einfach ab durch z.B. falsche Einstellungen im Spiel oder einem Fehler im Script oder so. Aber dies ist nicht so. Bei einem Absturz würde sich die Screen Session einfach beenden und gut. Hier wird ja eine neue Session gestartet und daher weiß ich das der Gameserver von "Außerhalb" neugestartet wird (cron z.B.)