Jump to content

Game frozen in Epoch Screen for 120 seconds


3Sgt.Edu

Recommended Posts

Hi guys,
First, sorry for my bad english!
 
I have a linux dayz epoch server that has this problem.
I could not identify any pattern that leads to this bug.
 
Sometimes it happens only to abort, go to the looby and try to return to the game.
For me I am an administrator, I see no problem because I just recreate my character changed the table "Alive" in mysql to 0 and then,I join with the server to recreate my character.
 
I see this bug happens on other servers too, and so I think that is some error in the codes of the epoch.
 
Would yours can to help me with some scripts to identify this error and automatically recreate the character for the player, stating that it was not possible to retrieve the information in the database because the players are trying to find administrators in the forum and teamspeak for help with this problem. Thus, if the process is automated, would facilitate much!
 
Dump of terminal server.
Here, the problem happens with the player ID [76561198119009356  / name "PlayerName"]
 
16:36:55 "infiSTAR.de PlayerDisconnected: _uid: 76561198119009356   _name: PlayerName"
16:36:55 "nil player object attempting PV, :["76561198119009356","PlayerName"]"
16:36:55 "get: STRING (), sent: STRING (76561198119009356)"
16:36:55 "DISCONNECT: PlayerName (76561198119009356) Object: B 1-1-C:1 REMOTE, _characterID: any at loc [6464.95,-1988.68,1.0277]"
16:36:55 "ERROR: Cannot Sync Character Stanislav Novak has nil characterID"
16:36:55 "CHILD:204:76561198119009356:"
16:36:55 Client: Remote object 11:0 not found
16:36:55 Client: Remote object 11:5 not found
16:36:55 "CHILD:103:76561198119009356:any:2:"
16:37:01 "CHILD:305:600:[39,[4735.91,12544,0.0214925]]:0.762713:"
16:37:01 "CHILD:306:600:[["wheel_1_2_steering",0.102362],["wheel_2_1_steering",0.0716514],["wheel_2_2_steering",0.137795],["palivo",0.145669],["motor",0.00393701],["glass1",0.00393701],["glass2",0.00393701],["glass3",0.00393701],["glass4",0.015748],["karoserie",0.12312]]:0.023622:"
16:37:30 "CLEANUP: Deleted 1 Loot Piles out of 42"
16:37:55 "WAI: [Mission:[Bandit] Black Hawk Crash]: Starting... [7382.37,11638.9,0]"
16:37:55 "WAI: Spawned a group of 3 AI (Hero) at [7382.37,11638.9,0]"
16:37:56 "WAI: Spawned a group of 3 AI (Hero) at [7382.37,11638.9,0]"
16:37:56 "WAI: Spawned a group of 3 AI (Hero) at [7382.37,11638.9,0]"
16:37:56 "WAI: Spawned in 2 M2StaticMG"
16:38:02 "infiSTAR.de PVAH_WriteLog: B 1-1-F:1 (3ºSgt.Edu) REMOTE   3ºSgt.Edu Spectating FyreDark"
16:38:46 "infiSTAR.de PlayerDisconnected: _uid: 76561197984468488   _name: 3ºSgt.Edu"
16:38:46 "get: STRING (76561197984468488), sent: STRING (76561197984468488)"
16:38:46 "DISCONNECT: 3ºSgt.Edu (76561197984468488) Object: B 1-1-F:1 (3ºSgt.Edu) REMOTE, _characterID: 204 at loc [4725.87,12569.4,0.00114441]"
16:38:46 "CHILD:201:204:[170,[4725.87,12569.4,0.00114441]]:[["ItemMap","ItemToolbox","ItemRadio","ItemCompass","Mk_48_DZ","ItemWatch","NVGoggles","Binocular_Vector","ItemKnife","ItemGPS","ItemFlashlight","M9","ItemEtool","ItemCrowbar"],["ItemBandage","ItemBandage","ItemBandage","ItemBandage","FoodSteakCooked","ItemGoldBar10oz","PartGeneric","100Rnd_762x51_M240","100Rnd_762x51_M240","100Rnd_762x51_M240","ItemBriefcase100oz","ItemBloodbag","15Rnd_9x19_M9","15Rnd_9x19_M9","15Rnd_9x19_M9","15Rnd_9x19_M9","ItemRuby"]]:["DZ_LargeGunBag_EP1",[["M9","M107_DZ","SCAR_L_STD_Mk4CQT","ItemMatchbox_DZE"],[1,1,1,1]],[["ItemSilverBar2oz","ItemGoldBar5oz","ItemJerryMixed3","30Rnd_556x45_Stanag","10Rnd_127x99_m107","ItemAntibiotic","FoodCanSardines","ItemPainkiller","ItemMorphine","ItemWaterbottle","FoodMRE"],[1,1,1,1,2,2,1,2,1,1,1]]]:[false,false,false,false,false,false,false,12000,[],[0,0],0,[6.75,35.0553]]:false:false:0:0:25:0:["Mk_48_DZ","amovpknlmstpsraswrfldnon",37,[]]:0:0::0:"
16:38:46 "CHILD:204:76561197984468488:"
16:38:46 Client: Remote object 12:24 not found
16:38:46 "CHILD:103:76561197984468488:204:2:"
16:42:18 "infiSTAR.de PlayerConnected: ["76561198119009356","PlayerName"]"
16:42:24 "CHILD:101:76561198119009356:1:PlayerName:"
16:42:24 "LOAD PLAYER: \cache\players\11\76561198119009356.sqf"
16:42:24 "PLAYER CACHE: ["PASS",false,"20",[309,[1930.88,11992.5,0.582269]],[["ItemFlashlight","ItemHatchet_DZE","ItemMap","ItemRadio","ItemToolbox","ItemCrowbar","ItemMatchbox_DZE","UZI_SD_EP1","ItemGPS","ItemKeyYellow1118","M24"],["30Rnd_9x19_UZI_SD","30Rnd_9x19_UZI_SD","30Rnd_9x19_UZI_SD","30Rnd_9x19_UZI_SD","ItemBandage","ItemBandage","5Rnd_762x51_M24","5Rnd_762x51_M24","5Rnd_762x51_M24","5Rnd_762x51_M24","5Rnd_762x51_M24","20Rnd_762x51_DMR","20Rnd_762x51_DMR","ItemMorphine","ItemBloodbag","ItemPainkiller","ItemSodaPepsi","FoodCanFrankBeans","ItemBandage","ItemBandage"]],["DZ_Backpack_EP1",[[],[]],[["ItemBloodbag","ItemAntibiotic","FoodCanBakedBeans","20Rnd_762x51_DMR","ItemMorphine","ItemPainkiller","ItemSodaPepsi"],[1,2,3,10,3,3,3]]],[3984,4000,4000],"GUE_Soldier_Sniper_DZ",0.96,0]"
16:42:24 "CHILD:11:12:"
16:42:25 Server: Object 11:17 not found (message 70)
16:42:25 "CHILD:102:20:"
16:42:25 "LOAD CHARACTER: \cache\players\12\76561198119009356-char.sqf"
16:42:25 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0.495822,0],0,[5.7,3.03333]],[13,12,0,8],["UZI_SD_EP1","aidlpknlmstpsraswpstdnon_player_0s",42,["76561198119009356","76561198119009356","76561198119009356","765611981190,[309,[1930.88,11992.5,0.582269]],3535,"20"]"
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]],3535,"20"]>
16:42:25   Error position: <20"]>
16:42:25   Error Missing ]
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]],3535,"20"]>
16:42:25   Error position: <20"]>
16:42:25   Error Missing ]
16:42:25 "CHILD:102:20:"
16:42:25 "LOAD CHARACTER: \cache\players\12\76561198119009356-char.sqf"
16:42:25 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0.495822,0],0,[5.7,3.03333]],[13,12,0,8],["UZI_SD_EP1","aidlpknlmstpsraswpstdnon_player_0s",42,["76561198119009356","76561198119009356","76561198119009356","765611981190,[309,[1930.88,11992.5,0.582269]],3535,"20"]"
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]],3535,"20"]>
16:42:25   Error position: <20"]>
16:42:25   Error Missing ]
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]]
my writer.pl
 
#!/usr/bin/perl
#
# Copyright 2014 by Denis Erygin,
# [email protected]
#

use JSON::XS;
use DBI;
use warnings;
use strict;

use constant {
    INSTANCE  => 1,           # Chernarus instance
    DB_NAME   => 'dayz_takistan',      # Set database name
    DB_LOGIN  => 'dayz',       # Set database login
    DB_PASSWD => 'mypass',       # Set database password
    DB_HOST   => 'localhost',  # Set database host
    DB_PORT   => 3306,         # Set database port (default 3306)

    CACHE_DIR => $ENV{'PWD'}.'/cache/',
    # Start inventory of player
    INVENTORY => '[["ItemFlashlight","ItemMap","ItemGPS","ItemCrowbar","ItemToolbox","glock17_EP1"],["17Rnd_9x19_glock17","17Rnd_9x19_glock17","ItemBandage","ItemBandage","ItemPainkiller","ItemSodaPepsi","ItemSodaCoke","FoodbeefCooked"]]',
    BACKPACK  => '["DZ_Patrol_Pack_EP1",[],[]]',
    MODEL     => '"Survivor2_DZ"'
};

my %cid_inv = ();
my %obj_inv = ();

my $myPlayerCounter = 1;

my %FN_IPC  = (
    11  => \&h_player_counter,
    21  => \&h_player_split_inventory,
    22  => \&h_player_split_backpack,
    31  => \&h_object_change_lock_code,
    33  => \&h_object_split_inventory,
    39  => \&h_object_uid_split_inventory,
    101 => \&h_load_player,
    103 => \&h_log_login,
    201 => \&h_player_update,
    202 => \&h_player_death,
    204 => \&h_player_disconnect,
    303 => \&h_object_update_inventory,
    304 => \&h_object_delete,
    305 => \&h_vehicle_moved,
    306 => \&h_vehicle_damaged,
    308 => \&h_object_publish,
    309 => \&h_object_uid_update_inventory,
    310 => \&h_object_uid_delete,
    396 => \&h_object_reset_damage,
    397 => \&h_object_uid_reset_damage,
    398 => \&h_trade_object,
);

my $dbh   = connect_to_db();
my $coder = JSON::XS->new->ascii(1)->shrink(1)->allow_nonref(1)->max_depth(5)->max_size(1048576);

mkdir (CACHE_DIR) unless (-d CACHE_DIR);

init_traders           ();
init_objects_id        ();
init_objects           ();
init_default_player    ();
init_default_character ();
update_players_cache   ();

open (LOG, ">>dump.log") or die $!;
while (<STDIN>) {
    next if ($_ =~ m/Duplicate magazine/ || $_ =~ m/arrived from nonowner/);
    print STDERR $_;
    print LOG $_;

    if ($_ =~ m/CHILD:/) {
        chop;
        my ($pref, $data) = split /CHILD:/ => $_;
        my @arr = split /:/ => $data;
        my $cmd = $arr[0];
        next unless $cmd;
        
        my $fn = $FN_IPC{$cmd};
        $fn->(\@arr) if $fn;
    } else {
        init_login_uid ($_);
    }
}
close(LOG);

$dbh->disconnect;
exit;

#---------------------------------------------------------------------------
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;
}

sub parse_json {
    my $str = shift;
    return unless $str;
    
    my $data;
    eval { $data = $coder->decode ($str); };
    return if $@;
    return $data;
}

sub init_traders {
    h_load_trader_details();
}

sub init_objects_id {
    h_load_objects_id();
}

sub init_objects {
    h_stream_objects();
}

sub init_default_player {
    my $file = CACHE_DIR.'players/default.sqf';
    open  (OUT, ">$file") or die "Can't open '$file'";
    print OUT '["PASS",false,"1",[],'.INVENTORY.','.BACKPACK.',[0,0,0],'.MODEL.',0.96,0]';
    close (OUT);
}

sub init_default_character {
    my $file = CACHE_DIR.'players/default-char.sqf';
    open  (OUT, ">$file") or die "Can't open '$file'";
    print OUT '["PASS",[],[0,0,0,0],[],[],2500,"1"]';
    close (OUT);
}

sub update_players_cache {
    my $sql = 'SELECT PlayerUID FROM Player_DATA';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ();
    return unless $res;
    
    my $PLAYERS_DIR = CACHE_DIR.'players/'.$myPlayerCounter;
    mkdir ($PLAYERS_DIR) unless (-d $PLAYERS_DIR);
    
    my @uids = ();
    while (my ($playerId) = $sth->fetchrow_array) {
        next unless $playerId;
        my $file = $PLAYERS_DIR.'/'.lc($playerId).'.sqf';
        next if (-f $file);
    
        push @uids, $playerId;
    }
    $sth->finish;
    return unless @uids;
    
    for my $playerId (@uids) {
        update_player_cache ($playerId);
    }
}

sub get_playerId_by_characterId {
    my $characterId = shift;
    return unless $characterId;
    
    my $sql = 'SELECT PlayerUID FROM Character_DATA WHERE CharacterID=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($characterId);
    return unless $res;
    
    my ($playerId) = $sth->fetchrow_array;
    $sth->finish;
    
    return $playerId;
}

sub update_player_cache {
    my $playerId = shift;
    return unless $playerId;

    my $sql = "SELECT CharacterID, Worldspace, Inventory, Backpack,
               TIMESTAMPDIFF(MINUTE, Datestamp, LastLogin) as SurvivalTime,
               TIMESTAMPDIFF(MINUTE, LastAte, NOW()) as MinsLastAte,
               TIMESTAMPDIFF(MINUTE, LastDrank, NOW()) as MinsLastDrank,
               Model, Humanity, KillsZ, HeadshotsZ, KillsH, KillsB, CurrentState, Medical, Infected 
               FROM Character_DATA
               WHERE PlayerUID=? AND Alive = 1 AND InstanceID=? ORDER BY CharacterID DESC LIMIT 1";
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($playerId, INSTANCE);
    #return unless $res;
    
    my ($characterId, $worldSpace, $inventory, $backpack, $survivalTime, $minsLastAte, $minsLastDrank, $model,
        $humanity, $killsZ, $headshotsZ, $killsH, $killsB, $currentState, $medical, $infected) = $sth->fetchrow_array;
    $sth->finish;
    return unless (defined $characterId);
    
    my $survival = '[0,0,0]';
    $survival    = '['.$survivalTime.','.$minsLastAte.','.$minsLastDrank.']' if (defined $survivalTime &&
                                                                                 defined $minsLastAte  &&
                                                                                 defined $minsLastDrank);
    my $PLAYERS_DIR = CACHE_DIR.'players/'.$myPlayerCounter;
    mkdir ($PLAYERS_DIR) unless (-d $PLAYERS_DIR);
                                                                                 
    my $file = $PLAYERS_DIR.'/'.lc($playerId).'.sqf';
    open  (OUT, ">$file") or print STDERR $!;
    print OUT '["PASS",false,"'.$characterId.'",'.$worldSpace.','.$inventory.','.$backpack.','.$survival.','.$model.',0.96,'.$infected.']';
    close (OUT);
        
    my $stats = '[0,0,0,0]';
    $stats    = '['.$killsZ.','.$headshotsZ.','.$killsH.','.$killsB.']' if (defined $killsZ && defined $headshotsZ && defined $killsH && defined $killsB);
    
    $file = $PLAYERS_DIR.'/'.lc($playerId).'-char.sqf';
    open  (OUT, ">$file") or print STDERR $!;
    print OUT '["PASS",'.$medical.','.$stats.','.$currentState.','.$worldSpace.','.$humanity.',"'.$characterId.'"]';
    close (OUT);
    
    return $characterId;
}

sub init_login_uid {
    my $dump = shift;
    return unless $dump;
        
    return unless ($dump =~ m/\sconnected/);
    return if ($dump =~ m/BattlEye Server: Player/);
    
    my ($p, $str)   = split (/Player\s/, $dump);
    return unless (defined $str);
    
    my ($name, $uid) = split (/\sconnected\s/, $str);
    return unless ($name && $uid);
    
    #if ($uid =~ m/(\d+)/) {
    if ($uid =~ m/=(\w+)/) {
        $uid = $1;
    } 
    return unless $uid;
    print STDERR "$uid => $name\n";
    
    #my $PLAYERS_DIR = CACHE_DIR.'players/'.$myPlayerCounter;
    #my $file        = $PLAYERS_DIR.'/'.$uid.'.sqf';
    #return if (-e $file);
    
    h_load_player ([101, $uid, INSTANCE, $name]);
}

# 11
sub h_player_counter {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $counter) = @$p;
    return unless ($counter && int($counter) > 0);
    $counter = int($counter);
    
    my $old = CACHE_DIR.'players/'.$myPlayerCounter;
    my $new = CACHE_DIR.'players/'.$counter;
    if (-d $old) {
        rename ($old, $new);
    } else {
        print STDERR "Error h_player_counter($counter): old '$myPlayerCounter' not found!\n";
        mkdir ($new) or print STDERR $!,"\n";
    }
    
    $myPlayerCounter = $counter;
}

# 21
sub h_player_split_inventory {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $cid, $idx, $data) = @$p;
    unless ($cid && defined $idx && defined $data) {
        print STDERR "Error h_player_split_inventory(): characterId or idx or data undefined!\n";
        return;
    }

    unless ( parse_json ($data) ) {
        print STDERR "Error h_player_split_inventory(): data invalid json!\n";
        $cid_inv{$cid} = undef;
        return;
    }

    # Save weapons
    if ($idx == 0) {
        $cid_inv{$cid} = $data;
        return;
    }
    # Save weapons + magazines
    if ($idx == 1 && $cid_inv{$cid}) {
        my $inv        = '['.$cid_inv{$cid}.','.$data.']';
        $cid_inv{$cid} = undef;
        print STDERR "Size plr inv: ".length($inv)."\n";

        unless ( parse_json($inv) ) {
            print STDERR "Error h_player_split_inventory(): inventory invalid json!\n";
            return;
        }

        my $sth = $dbh->prepare ('UPDATE Character_DATA SET Inventory=? WHERE CharacterID=?');
        my $res = $sth->execute ($cid, $inv);
        return $res;
    }
}

# 22
sub h_player_split_backpack {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $cid, $data) = @$p;
    unless ($cid && defined $data) {
        print STDERR "Error h_player_split_backpack(): characterId or data undefined!\n";
        return;
    }

    unless ( parse_json ($data) ) {
        print STDERR "Error h_player_split_backpack(): backpack invalid json!\n";
        return;
    }
    return if ($data eq '[]');

    my $sth = $dbh->prepare ('UPDATE Character_DATA SET Backpack=? WHERE CharacterID=?');
    my $res = $sth->execute ($cid, $data);
    return $res;
}

# 31
sub h_object_change_lock_code {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $oid, $code) = @$p;
    unless ($oid && $code) {
        print STDERR "Error h_object_change_lock_code(): objectId or code undefined!\n";
        return;
    }
    $oid =~ s/"//g;
    
    my $sth = $dbh->prepare ('UPDATE Object_DATA SET CharacterID=? WHERE ObjectID=? AND Instance=?');
    my $res = $sth->execute ($code, $oid, INSTANCE);
    return $res;
}

# 33
sub h_object_split_inventory {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $oid, $idx, $data) = @$p;
    unless ($oid && defined $idx && defined $data) {
        print STDERR "Error h_object_split_inventory(): objectId or idx or data undefined!\n";
        return;
    }
    $oid =~ s/"//g;

    unless ( parse_json ($data) ) {
        print STDERR "Error h_object_split_inventory($oid): data invalid json!\n";
        $obj_inv{$oid} = undef;
        return;
    }

    # Save weapons
    if ($idx == 0) {
        $obj_inv{$oid} = $data;
        return;
    }
    # Save weapons + magazines
    if ($idx == 1 && $obj_inv{$oid}) {
        $obj_inv{$oid} .= ','.$data;
        return;
    }
    # Save weapons + magazines + backpack
    if ($idx == 2 && $obj_inv{$oid}) {
        my $inv        = '['.$obj_inv{$oid}.','.$data.']';
        $obj_inv{$oid} = undef;
        print STDERR "Size obj inv: ".length($inv)."\n";

        unless ( parse_json($inv) ) {
            print STDERR "Error h_object_split_inventory($oid): inventory invalid json!\n";
            return;
        }

        my $sth = $dbh->prepare ('UPDATE Object_DATA SET Inventory=? WHERE ObjectID=? AND Instance=?');
        my $res = $sth->execute ($inv, $oid, INSTANCE);
        return $res;
    }
}

# 39
sub h_object_uid_split_inventory {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $uid, $idx, $data) = @$p;
    unless ($uid && defined $idx && defined $data) {
        print STDERR "Error h_object_uid_split_inventory(): objectUID or idx or data undefined!\n";
        return;
    }
    $uid =~ s/"//g;

    unless ( parse_json ($data) ) {
        print STDERR "Error h_object_uid_split_inventory($uid): data invalid json!\n";
        $obj_inv{$uid} = undef;
        return;
    }

    # Save weapons
    if ($idx == 0) {
        $obj_inv{$uid} = $data;
        return;
    }
    # Save weapons + magazines
    if ($idx == 1 && $obj_inv{$uid}) {
        $obj_inv{$uid} .= ','.$data;
        return;
    }
    # Save weapons + magazines + backpack
    if ($idx == 2 && $obj_inv{$uid}) {
        my $inv        = '['.$obj_inv{$uid}.','.$data.']';
        $obj_inv{$uid} = undef;
        print STDERR "Size obj uid inv: ".length($inv)."\n";

        unless ( parse_json($inv) ) {
            print STDERR "Error h_object_uid_split_inventory($uid): inventory invalid json!\n";
            return;
        }

        my $sth = $dbh->prepare ('UPDATE Object_DATA SET Inventory=? WHERE ObjectUID=? AND Instance=?');
        my $res = $sth->execute ($inv, $uid, INSTANCE);
        return $res;
    }
}

# 101
sub h_load_player {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $playerId, $serverId, $playerName) = @$p;
    unless ($playerId && $serverId) {
        print STDERR "Error h_load_player(): playerId or serverId undefined!\n";
        return;
    }
    $playerId =~ s/['"]//g;
    $serverId ||= INSTANCE;
    
    my $PLAYERS_DIR = CACHE_DIR.'players/'.$myPlayerCounter;
    mkdir ($PLAYERS_DIR) unless (-d $PLAYERS_DIR);
    
    my $sql = 'SELECT PlayerName, PlayerSex FROM Player_DATA WHERE PlayerUID=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($playerId);
    
    my ($name, $sex) = $sth->fetchrow_array;
    $sth->finish;
    
    my $newPlayer = 0;
    if (defined $name) {
        if ($playerName && $playerName ne $name) {
            $sql = 'UPDATE Player_DATA SET PlayerName=? WHERE PlayerUID=?';
            $sth = $dbh->prepare ($sql);
            $res = $sth->execute ($playerName, $playerId);
            print STDERR "Changed name of player $playerId from '$name' to '$playerName'\n";
        }
    } else {
        $newPlayer  = 1;
        $playerName = 'Unknown' unless $playerName;
        
        $sql = 'INSERT INTO Player_DATA(PlayerUID, PlayerName) VALUES (?, ?)';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($playerId, $playerName);
        print STDERR "Created a new player $playerId named '$playerName'\n";
    }
    
    $sql = "SELECT CharacterID, Worldspace, Inventory, Backpack, 
            TIMESTAMPDIFF(MINUTE, Datestamp, LastLogin) as SurvivalTime,
            TIMESTAMPDIFF(MINUTE, LastAte, NOW()) as MinsLastAte, 
            TIMESTAMPDIFF(MINUTE, LastDrank, NOW()) as MinsLastDrank,
            Model, Medical, Humanity, KillsZ, HeadshotsZ, KillsH, KillsB, CurrentState, Infected  
            FROM  Character_DATA 
            WHERE PlayerUID=? AND Alive = 1 AND InstanceID=? ORDER BY CharacterID DESC LIMIT 1";
    $sth = $dbh->prepare ($sql);
    $res = $sth->execute ($playerId, $serverId);
    
    my ($characterId, $worldSpace, $inventory, $backpack, $survivalTime, $minsLastAte, $minsLastDrank, 
        $model, $medical, $humanity, $killsZ, $headshotsZ, $killsH, $killsB, $currentState, $infected) = $sth->fetchrow_array;
    $sth->finish;
    
    $currentState = '[]'      unless (defined $currentState);
    $humanity     = 2500      unless (defined $humanity);
    $infected     = 0         unless (defined $infected);
    $medical      = '[]'      unless (defined $medical);
    $worldSpace   = '[]'      unless (defined $worldSpace);
    $inventory    = INVENTORY unless (defined $inventory);  # '[]'
    $backpack     = BACKPACK  unless (defined $backpack);   # '[]'
    $model        = MODEL     unless (defined $model);      # ''
    
    my $survival = '[0,0,0]';
    $survival    = '['.$survivalTime.','.$minsLastAte.','.$minsLastDrank.']' if (defined $survivalTime && 
                                                                                 defined $minsLastAte  && 
                                                                                 defined $minsLastDrank);
    my $newChar = 0;
    if (defined $characterId) {
        $sql = 'UPDATE Character_DATA SET LastLogin = CURRENT_TIMESTAMP WHERE CharacterID=?';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($characterId);
        
        my $stats = '[0,0,0,0]';
        $stats    = '['.$killsZ.','.$headshotsZ.','.$killsH.','.$killsB.']' if (defined $killsZ && defined $headshotsZ &&
                                                                                defined $killsH && defined $killsB);        
        my $file = $PLAYERS_DIR.'/'.lc($playerId).'-char.sqf';
        open  (OUT, ">$file");
        print OUT '["PASS",'.$medical.','.$stats.','.$currentState.','.$worldSpace.','.$humanity.',"'.$characterId.'"]';
        close (OUT); 
    } else {
        $newChar = 1;
        
        $sql = "SELECT Generation, Humanity, Model, Infected FROM Character_DATA 
                WHERE PlayerUID=? AND Alive = 0 AND InstanceID=? ORDER BY CharacterID DESC LIMIT 1";
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($playerId, $serverId);
        
        my ($generation, $humanity, $cmodel, $infected) = $sth->fetchrow_array;
        $sth->finish;
        
        if (defined $generation) {
            $generation++;
        } else {
            $generation = 1;
        }
        
        $humanity = 2500    unless (defined $humanity);
        $infected = 0       unless (defined $infected);
        $model    = $cmodel if (defined $cmodel); 
        
        $sql = "INSERT INTO Character_DATA(PlayerUID, InstanceID, Worldspace, Inventory, Backpack, Medical,
                                           Generation, Datestamp, LastLogin, LastAte, LastDrank, Humanity, Infected) 
                VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?, ?)";
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($playerId, $serverId, $worldSpace, $inventory, $backpack, $medical, $generation, $humanity, $infected);
        
        $sql = 'SELECT CharacterID FROM Character_DATA WHERE PlayerUID=? AND Alive = 1 AND InstanceID=? ORDER BY CharacterID DESC LIMIT 1';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($playerId, $serverId);
        
        ($characterId) = $sth->fetchrow_array;
        $sth->finish;
        
        $playerName = 'Unknown' unless $playerName;
        
        if (defined $characterId) {
            print STDERR "Created a new character $characterId for player '$playerName' ($playerId)\n";
            my $file = $PLAYERS_DIR.'/'.lc($playerId).'-char.sqf';
            open  (OUT, ">$file");
            print OUT '["PASS",'.$medical.',[0,0,0,0],[],'.$worldSpace.','.$humanity.',"'.$characterId.'"]';
            close (OUT);
        } else {
            print STDERR "Can't found new character for player '$playerName' ($playerId)\n";
        }
    }
    
    my $file = $PLAYERS_DIR.'/'.lc($playerId).'.sqf';
    open  (OUT, ">$file");
    print OUT '["PASS",false,"'.$characterId.'",'.$worldSpace.','.$inventory.','.$backpack.','.$survival.','.$model.',0.96,'.$infected.']';
    close (OUT);
    
    print STDERR "Save player: $file\n";
    return $res;
}

# 102
sub h_load_character {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $characterId, $playerId) = @$p;
    unless ($characterId) {
        print STDERR "Error h_load_character(): characterId undefined!\n";
        return;
    }
    $characterId =~ s/"//g;
    $playerId    =~ s/['"]//g;
    
    if ($characterId == 1 && $playerId) {
        my $sql = 'SELECT CharacterID FROM Character_DATA WHERE PlayerUID=? AND Alive = 1 AND InstanceID=? ORDER BY CharacterID DESC LIMIT 1';
        my $sth = $dbh->prepare ($sql);
        my $res = $sth->execute ($playerId, INSTANCE);
        return unless $res;
        
        ($characterId) = $sth->fetchrow_array;
        $sth->finish;
    }
    unless ($characterId) {
        print STDERR "Error h_load_character(): characterId undefined!\n";
        return;
    }
    
    my $sql = "SELECT Worldspace, Medical, Generation, KillsZ, HeadshotsZ, KillsH, KillsB, CurrentState, Humanity, PlayerUID 
               FROM Character_DATA WHERE CharacterID=?";
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($characterId);
    
    my ($worldSpace, $medical, $generation, $killsZ, $headshotsZ, $killsH, $killsB, $currentState, $humanity, $playerUID) = $sth->fetchrow_array;
    $sth->finish;
    return unless (defined $worldSpace);
    
    $playerId = $playerUID if (defined $playerUID);
    
    $worldSpace   ||= '[]';
    $medical      ||= '[]';
    $generation   ||= 1;
    $currentState ||= '[]';
    $humanity       = 2500 unless (defined $humanity);
    
    my $stats = '[0,0,0,0]';
    $stats    = '['.$killsZ.','.$headshotsZ.','.$killsH.','.$killsB.']' if (defined $killsZ && defined $headshotsZ && 
                                                                            defined $killsH && defined $killsB);
    
    my $file = CACHE_DIR.'players/'.$myPlayerCounter.'/'.lc($playerId).'-char.sqf';
    open  (OUT, ">$file");
    print OUT '["PASS",'.$medical.','.$stats.','.$currentState.','.$worldSpace.','.$humanity.',"'.$characterId.'"]';
    close (OUT);
    
    print STDERR "Save character: $file\n";
    return $res;
}

# 103
sub h_log_login {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $playerId, $characterId, $action) = @$p;
    unless ($playerId) {
        print STDERR "Error h_log_login(): playerId undefined!\n";
        return;
    }
    $playerId    =~ s/['"]//g;
    $characterId =~ s/"//g;
    
    my $sql = 'INSERT INTO Player_LOGIN(PlayerUID, CharacterID, Datestamp, Action) VALUES (?, ?, CURRENT_TIMESTAMP, ?)';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($playerId, $characterId, $action);
    return $res;
}

# 201
sub h_player_update {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $characterId, $worldSpace, $inventory, $backpack, $medical, $justAte, $justDrank, 
        $killsZ, $headshotsZ, $distanceWalked, $durationLived, $currentState, $killsH, $killsB, $model,
        $humanity) = @$p;
    unless ($characterId) {
        print STDERR "Error h_player_update(): characterId undefined!\n";
        return;
    }
    $characterId =~ s/"//g;
    
    if ($worldSpace) {
        my $ws = parse_json ($worldSpace);
        unless ($ws) {
            print STDERR "Error h_player_update(): worldSpace invalid json!\n";
            return;
        }
        if (@$ws) {
            if ($ws->[1] && ref($ws->[1]) eq 'ARRAY') {
                my ($x, $y) = @{$ws->[1]};
                if ($x && $x < -18000) {
                    print STDERR "Error h_player_update(): worldSpace invalid!\n";
                    return;
                }
            }
        }
    }
    if ($inventory) {
        unless ( parse_json ($inventory) ) {
            print STDERR "Error h_player_update(): inventory invalid json!\n";
            $inventory = undef;
        }
    }
    if ($backpack) {
        unless ( parse_json ($backpack) ) {
            print STDERR "Error h_player_update(): backpack invalid json!\n";
            $backpack = undef;
        }
    }
    if ($medical) {
        unless ( parse_json ($medical) ) {
            print STDERR "Error h_player_update(): medical invalid json!\n";
            $medical = undef;
        }
    }
    if ($currentState) {
        unless ( parse_json ($currentState) ) {
            print STDERR "Error h_player_update(): currentState invalid json!\n";
            $currentState = undef;
        }
    }
    if ($model) {
        $model = '"'.$model.'"' if (length($model) > 3 && $model !~ m/"/);
        unless ( parse_json ($model) ) {
            print STDERR "Error h_player_update(): model invalid json!\n";
            $model = undef;
        }
    }
    
    my $str = '';
    $str .= 'Worldspace='.$dbh->quote($worldSpace).','            if ($worldSpace && $worldSpace ne '[]');
    $str .= 'Inventory='.$dbh->quote($inventory).','              if ($inventory  && $inventory  ne INVENTORY && $inventory ne '[]');
    $str .= 'Backpack='.$dbh->quote($backpack).','                if ($backpack   && $backpack   ne BACKPACK && $backpack ne '[]');
    $str .= 'Medical='.$dbh->quote($medical).','                  if ($medical    && $medical    ne '[]');
    $str .= 'CurrentState='.$dbh->quote($currentState).','        if ($currentState && $currentState ne '[]');
    $str .= 'Model='.$dbh->quote($model).','                      if ($model && $model ne MODEL);
    
    $str .= 'LastAte=CURRENT_TIMESTAMP,'                          if ($justAte   && $justAte   eq 'true');
    $str .= 'LastDrank=CURRENT_TIMESTAMP,'                        if ($justDrank && $justDrank eq 'true');
    
    $str .= 'KillsZ=KillsZ+'.int($killsZ).','                     if ($killsZ     && $killsZ > 0);
    $str .= 'HeadshotsZ=HeadshotsZ+'.int($headshotsZ).','         if ($headshotsZ && $headshotsZ > 0);
    $str .= 'DistanceFoot=DistanceFoot+'.int($distanceWalked).',' if ($distanceWalked && $distanceWalked > 0);
    $str .= 'KillsH=KillsH+'.int($killsH).','                     if ($killsH     && $killsH > 0);
    $str .= 'KillsB=KillsB+'.int($killsB).','                     if ($killsB     && $killsB > 0);
    
    if ($humanity) {    
        if ($humanity < 0) {
            $str .= 'Humanity=Humanity-'.int(-1*$humanity).',';
        } else {
            $str .= 'Humanity=Humanity+'.int($humanity).',';
        }
    }
     
    return unless $str;
    
    $str .= 'Duration=Duration+'.int($durationLived || 0);
    
    my $sql = 'UPDATE Character_DATA SET ';
    $sql   .= $str;
    $sql   .= ' WHERE CharacterID=?';
    
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($characterId);
    return $res;
}

# 202
sub h_player_death {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $characterId, $duration, $playerid, $infected) = @$p;
    unless ($characterId) {
        print STDERR "Error h_player_death(): characterId undefined!\n";
        return;
    }
    $characterId =~ s/"//g;
    
    my $sql =  "UPDATE Character_DATA SET Alive = 0, LastLogin = DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? MINUTE) , Infected = ?
                WHERE CharacterID=? AND Alive = 1";
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute (int($duration), $infected, $characterId);
    return unless $res;    
    
    # Reset profile
    my $playerId = get_playerId_by_characterId ($characterId);
    if ($playerId) {    
        h_load_player ([101, $playerId, INSTANCE]);
    } else {
        print STDERR "Error h_player_death('$characterId'): playerId not found!\n";
    }
}

# 204
sub h_player_disconnect {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $playerId) = @$p;
    $playerId =~ s/[A-Z"]//g;
    
    update_player_cache ($playerId);
}

# 302
sub h_stream_objects {
    # Clean objects
    for my $sql ('DELETE FROM Object_DATA WHERE Instance=? AND ClassName="TentStorage" AND (Inventory="[[[],[]],[[],[]],[[],[]]]" OR Damage=1)',
                 'DELETE FROM Object_DATA where Instance=? AND Damage > 0.9 AND ObjectID > 89') {
        my $sth = $dbh->prepare ($sql);
        $sth->execute (INSTANCE);
    }
    
    my $sql = "SELECT ObjectID, CharacterID, Worldspace, Inventory, Hitpoints, Fuel, Damage 
                 FROM Object_init_DATA WHERE Instance=? AND Classname IS NOT NULL ORDER BY ObjectID";
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute (INSTANCE);
    return unless $res;
    
    my %init = ();
    while (my ($objId, $ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage) = $sth->fetchrow_array) {
        next unless $objId;

        $ownerId    ||= 0;
        $worldSpace ||= '[]';
        $inventory  ||= '[]';
        $hitpoints  ||= '[]';
        $fuel       ||= 0;
        $damage     ||= 0;
    
        $init{$objId} = [$ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage];
    }
    $sth->finish;
    
    $sql = "SELECT ObjectID, Classname, CharacterID, Worldspace, Inventory, Hitpoints, Fuel, Damage
            FROM Object_DATA WHERE Instance=? AND Classname IS NOT NULL ORDER BY ObjectID";
    $sth = $dbh->prepare ($sql);
    $res = $sth->execute (INSTANCE);
    return unless $res;
    
    my $str     = '';
    my @updates = ();
    while (my ($objId, $className, $ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage) = $sth->fetchrow_array) {
        if ( $objId && $damage && $damage > 0.7 && $init{$objId} ) {
            print STDERR "Respawn '$className' ($objId)\n";
            ($ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage) = @{$init{$objId}};
            push @updates, $objId;
        }
        
        $ownerId    ||= 0;
        $worldSpace ||= '[]';
        $inventory  ||= '[]';
        $hitpoints  ||= '[]';
        $fuel       ||= 0;
        $damage     ||= 0;
        
        $fuel   = sprintf ("%.3f", $fuel);
        $damage = sprintf ("%.3f", $damage);
        
        $str .= ',' if $str;
        $str .= '["OBJ","'.$objId.'","'.$className.'","'.$ownerId.'",'.$worldSpace.','.$inventory.','.$hitpoints.','.$fuel.','.$damage.']';
    }
    $sth->finish;
    
    for my $objId (@updates) {
        my ($ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage) = @{$init{$objId}};
        $sql = 'UPDATE Object_DATA SET CharacterID=?, Worldspace=?, Inventory=?, Hitpoints=?, Fuel=?, Damage=? WHERE Instance=? AND ObjectID=?';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($ownerId, $worldSpace, $inventory, $hitpoints, $fuel, $damage, INSTANCE, $objId);
    }    
    #return unless $str;
    
    my $file = CACHE_DIR.'objects.sqf';
    open  (OUT, ">$file");
    print OUT '['.$str.']';
    close (OUT);    
}

# 303
sub h_object_update_inventory {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectId, $inventory) = @$p;
    unless ($objectId && $inventory) {
        print STDERR "Error h_object_update_inventory(): objectId or inventory undefined!\n";
        return;
    }
    $objectId =~ s/"//g;
    
    unless ( parse_json ($inventory) ) {
        print STDERR "Error h_object_update_inventory($objectId): inventory invalid json!\n";
        return;
    }
    
    my $sql = 'UPDATE Object_DATA SET Inventory=? WHERE ObjectID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($inventory, $objectId, INSTANCE);
    return $res;
}

# 304
sub h_object_delete {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectId) = @$p;
    unless ($objectId) {
        print STDERR "Error h_object_delete(): objectId undefined!\n";
        return;
    }
    $objectId =~ s/"//g;
    
    my $sql = 'DELETE FROM Object_DATA WHERE ObjectID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($objectId, INSTANCE);
    
    if ($res) {
        $sql = 'DELETE FROM Object_init_DATA WHERE ObjectID=? AND Instance=?';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($objectId, INSTANCE);
    }    
    return $res;
}

# 305
sub h_vehicle_moved {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectId, $worldSpace, $fuel) = @$p;
    unless ($objectId && $worldSpace) {
        print STDERR "Error h_vehicle_moved(): objectId undefined!\n";
        return;
    }
    $objectId =~ s/"//g;
    
    unless ( parse_json ($worldSpace) ) {
        print STDERR "Error h_vehicle_moved($objectId): worldSpace invalid json!\n";
        return;
    }
    
    my $sql = 'UPDATE Object_DATA SET Worldspace=?, Fuel=? WHERE ObjectID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($worldSpace, $fuel, $objectId, INSTANCE);
    return $res;
}

# 306
sub h_vehicle_damaged {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectId, $hitPoints, $damage) = @$p;
    unless ($objectId && defined $hitPoints && defined $damage) {
        print STDERR "Error h_vehicle_damaged(): objectId undefined!\n";
        return;
    }
    $objectId =~ s/"//g;
    
    if ($hitPoints) {
        unless ( parse_json ($hitPoints) ) {
            print STDERR "Error h_vehicle_damaged($objectId): hitPoints invalid json!\n";
            return;
        }
    }
    
    $hitPoints ||= '[]';
    $damage    ||= 0;
    
    my $sql = 'UPDATE Object_DATA SET Hitpoints=?, Damage=? WHERE ObjectID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($hitPoints, $damage, $objectId, INSTANCE);
    return $res;
}

# 308
sub h_object_publish {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $serverId, $className, $damage, $characterId, $worldSpace, $inventory, $hitPoints, $fuel, $objectUID) = @$p;
    unless ($className) {
        print STDERR "Error h_object_publish(): className undefined!\n";
        return;
    }
    $characterId =~ s/"//g;
    $objectUID   =~ s/"//g;
    
    if ($worldSpace) {
        unless ( parse_json ($worldSpace) ) {
            print STDERR "Error h_object_publish($className): worldSpace invalid json!\n";
            return;
        }
    }
    if ($inventory) {
        unless ( parse_json ($inventory) ) {
            print STDERR "Error h_object_publish($className): inventory invalid json!\n";
            $inventory = '[]';
        }
    }
    if ($hitPoints) {
        unless ( parse_json ($hitPoints) ) {
            print STDERR "Error h_object_publish($className): hitPoints invalid json!\n";
            $hitPoints = '[]';
        }
    }
    
    $serverId   ||= INSTANCE;
    $worldSpace ||= '[]';
    $inventory  ||= '[]';
    $hitPoints  ||= '[]';
    $damage     ||= 0;
    $fuel       ||= 0;
    
    my $sql = "INSERT INTO Object_DATA(ObjectUID, Instance, Classname, Damage, CharacterID, Worldspace, Inventory, 
                                       Hitpoints, Fuel, Datestamp) 
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)";
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($objectUID, $serverId, $className, $damage, $characterId, $worldSpace, $inventory, $hitPoints, $fuel);
    
    # Cache object ID
    $sql = 'SELECT ObjectID FROM Object_DATA WHERE ObjectUID=? AND Instance=?';
    $sth = $dbh->prepare ($sql);
    $res = $sth->execute ($objectUID, $serverId);
    return unless $res;
                
    my ($objectId) = $sth->fetchrow_array;
    $sth->finish;
    return unless (defined $objectId);

    my $file = CACHE_DIR.'objects/'.$objectUID.'.sqf';
    open  (OUT, ">$file");
    print OUT '["PASS","'.$objectId.'"]';
    close (OUT);
}

# 309
sub h_object_uid_update_inventory {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectUID, $inventory) = @$p;
    unless ($objectUID && $inventory) {
        print STDERR "Error h_object_uid_update_inventory(): objectUID or inventory undefined!\n";
        return;
    }
    $objectUID =~ s/"//g;
    
    unless ( parse_json ($inventory) ) {
        print STDERR "Error h_object_uid_update_inventory($objectUID): inventory invalid json!\n";
        return;
    }
    
    my $sql = 'UPDATE Object_DATA SET Inventory=? WHERE ObjectUID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($inventory, $objectUID, INSTANCE);
    return $res;
}

# 310
sub h_object_uid_delete {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $objectUID) = @$p;
    unless ($objectUID) {
        print STDERR "Error h_object_uid_delete(): objectUID undefined!\n";
        return;
    }
    $objectUID =~ s/"//g;
    
    my $sql = 'DELETE FROM Object_DATA WHERE ObjectUID=? AND Instance=?';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($objectUID, INSTANCE);
    
    if ($res) {
        $sql = 'DELETE FROM Object_init_DATA WHERE ObjectUID=? AND Instance=?';
        $sth = $dbh->prepare ($sql);
        $res = $sth->execute ($objectUID, INSTANCE);
    }
    return $res;
}

# 388 - loadObjectID
sub h_load_objects_id {
    my $sql = 'SELECT ObjectID, ObjectUID FROM Object_DATA WHERE Instance=? ORDER BY ObjectUID';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute (INSTANCE);
    #return unless $res;
    
    while (my ($objectId, $objectUID) = $sth->fetchrow_array) {
        next unless (defined $objectId);
        
        my $file = CACHE_DIR.'objects/'.$objectUID.'.sqf';
        open  (OUT, ">$file");
        print OUT '["PASS","'.$objectId.'"]';
        close (OUT);
    }
    $sth->finish;
}

# 396
sub h_object_reset_damage {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $oid) = @$p;
    unless ($oid) {
        print STDERR "Error h_object_reset_damage(): objectId undefined!\n";
        return;
    }
    $oid =~ s/"//g;
    
    my $sth = $dbh->prepare ('UPDATE Object_DATA SET Damage=0 WHERE ObjectID=? AND Instance=?');
    my $res = $sth->execute ($oid, INSTANCE);
    return $res;
}

# 397
sub h_object_uid_reset_damage {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $uid) = @$p;
    unless ($uid) {
        print STDERR "Error h_object_uid_reset_damage(): objectUID undefined!\n";
        return;
    }
    $uid =~ s/"//g;
    
    my $sth = $dbh->prepare ('UPDATE Object_DATA SET Damage=0 WHERE ObjectUID=? AND Instance=?');
    my $res = $sth->execute ($uid, INSTANCE);
    return $res;
}

# 398 - tradeObject 
sub h_trade_object {
    my $p = shift;
    return unless ($p && ref($p) eq 'ARRAY');
    my ($cmd, $traderObjectId, $action) = @$p;
    return unless ($traderObjectId && defined $action);
    
    my $sql;
    if ($action == 0) {
        $sql = 'UPDATE Traders_DATA SET qty = qty - 1 WHERE id=? AND qty > 0';
    } else {
        $sql = 'UPDATE Traders_DATA SET qty = qty + 1 WHERE id=?';
    }
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ($traderObjectId);    
    return $res;
}

# 399 - loadTraderDetails
sub h_load_trader_details {
    my $sql = 'SELECT id, item, qty, buy, sell, `order`, tid, afile FROM Traders_DATA';
    my $sth = $dbh->prepare ($sql);
    my $res = $sth->execute ();
    return unless $res;
    
    my %tids = ();
    my $charecterId = 0;
    while (my ($id, $item, $qty, $buy, $sell, $order, $tid, $afile) = $sth->fetchrow_array) {
        next unless $tid;
        $tids{$tid} = [] unless $tids{$tid};
        
        push @{$tids{$tid}}, '['.$id.','.$item.','.$qty.','.$buy.','.$sell.','.$order.','.$tid.',"'.$afile.'"]';
    }     
    $sth->finish;
    
    return unless %tids;
    
    while (my ($tid, $v) = each %tids) {
        next unless ($v && @$v);
        my $str = join (',', @$v);
    
        my $file = CACHE_DIR.'traders/'.$tid.'.sqf';
        open  (OUT, ">$file");
        print OUT '['.$str.']';
        close (OUT);
    }
    
    undef %tids;
}

Thank you!

Link to comment
Share on other sites

Thanks friend, but that does not solve the problema. I always having to delete data from any player or set it with alive = 0 in database. And this happens very often, about 5 times a day, each time with a player and sometimes myself.
My idea is to automate the repair, if the player data are inconsistent automatically during in loadscreen of dayz epoch, show the option to choose the gender as if he had died and respawn again
Link to comment
Share on other sites

Hm, did you use the writer.pl from the link I guess. I need to check this. I get no errors on my server. I will copy the writer.pl from the link to my server and check again.

Or did you change anything manually?

 

0s",42,["76561198119009356","76561198119009356","76561198119009356","765611981190,[3

 

That looks like player IDs? Whare are these coming from? Is this from the normal friend system? The last player uid is missing a " at the end as it seems.

Link to comment
Share on other sites

The links are in the video description:

 

Link to new server_playerLogin.sqf (dayz_server.pbo)
----------------------------------------­----------------------------------------
http://pastebin.com/c8TfvvhS

Link to new writer.pl:
----------------------------------------­----------------------------------------
http://pastebin.com/GMhQhSjh

 

Better to take this one. I guess there is whatever error in the manually modified files.

 

 

Link to comment
Share on other sites

My writer.pl was ok however found differences in server_playerLogin.sqf
 
Today I tried to connect and happened to me, I stay freeze in the Epoch loadscreen.
 9:45:03 "infiSTAR.de PlayerConnected: ["76561197984468488","3ºSgt.Edu"]"
 9:45:03 "infiSTAR.de - Player-Log: 3ºSgt.Edu(76561197984468488) - 1h 11min | ******ADMIN******"
 9:45:06 "CHILD:201:126:[302,[4732.34,12556.2,0.00167315]]:[["Binocular_Vector","NVGoggles","ItemMap","ItemToolbox","ItemRadio","ItemCompass","ItemHatchet_DZE","ItemCrowbar","ItemMachete","ItemEtool","ItemKnife","ItemGPS","ItemMatchbox_DZE","Mk_48_DZ"],[["100Rnd_762x51_M240",94],"100Rnd_762x51_M240","cinder_wall_kit","cinder_wall_kit","cinder_wall_kit","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage"]]:["DZ_LargeGunBag_EP1",[[],[]],[["MortarBucket","CinderBlocks"],[10,22]]]:[false,false,false,false,false,false,true,12000,[],[0,0],0,[159.975,102.16]]:false:false:0:0:4:1:["Mk_48_DZ","ainvpknlmstpslaywrfldnon_amovpknlmstpsraswrfldnon",41,["76561198034065410","76561198034065410"]]:0:0::0:"
 9:45:14 "CHILD:101:76561197984468488:1:3ºSgt.Edu:"
 9:45:15 "LOAD PLAYER: \cache\players\6\76561197984468488.sqf"
 9:45:15 "PLAYER CACHE: ["PASS",false,"213",[75,[5286.79,11151.6,0.00146132]],[["ItemMap","ItemToolbox","ItemRadio","ItemCompass","ItemWatch","Binocular_Vector","ItemKnife","ItemGPS","ItemFlashlight","M9","ItemEtool","ItemCrowbar","NVGoggles","Mk_48_DZ"],["ItemBandage","ItemBandage","ItemBandage","ItemBandage","FoodSteakCooked","ItemGoldBar10oz","PartGeneric","ItemBriefcase100oz","ItemBloodbag","15Rnd_9x19_M9","15Rnd_9x19_M9","15Rnd_9x19_M9","15Rnd_9x19_M9","ItemRuby","100Rnd_762x51_M240","100Rnd_762x51_M240","ItemBriefcase100oz","ItemBriefcase100oz"]],["DZ_LargeGunBag_EP1",[["M9","M107_DZ","SCAR_L_STD_Mk4CQT","ItemMatchbox_DZE"],[1,1,1,1]],[["ItemSilverBar2oz","ItemGoldBar5oz","ItemJerryMixed3","30Rnd_556x45_Stanag","10Rnd_127x99_m107","ItemAntibiotic","FoodCanSardines","ItemPainkiller","ItemMorphine","ItemWaterbottle","FoodMRE"],[1,1,1,1,2,2,1,2,1,1,1]]],[10,406,406],"Survivor2_DZ",0.96,0]"
 9:45:15 "CHILD:11:7:"
 9:45:15 Server: Object 6:6 not found (message 70)
 9:45:15 "CHILD:102:213:"
 9:45:15 "LOAD CHARACTER: \cache\players\7\76561197984468488-char.sqf"
 9:45:15 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0,0],0,[7.1,17.4801]],[0,0,0,0],["M9","aidlpercmstpsraswpstdnon_player_idlesteady01",42,["76561197984468488","76561197984468488","76561197984468488","7656119798,[75,[5286.79,11151.6,0.00146132]],8221,"213"]"
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 "CHILD:102:213:"
 9:45:15 "LOAD CHARACTER: \cache\players\7\76561197984468488-char.sqf"
 9:45:15 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0,0],0,[7.1,17.4801]],[0,0,0,0],["M9","aidlpercmstpsraswpstdnon_player_idlesteady01",42,["76561197984468488","76561197984468488","76561197984468488","7656119798,[75,[5286.79,11151.6,0.00146132]],8221,"213"]"
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 "CHILD:102:213:"
 9:45:15 "LOAD CHARACTER: \cache\players\7\76561197984468488-char.sqf"
 9:45:15 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0,0],0,[7.1,17.4801]],[0,0,0,0],["M9","aidlpercmstpsraswpstdnon_player_idlesteady01",42,["76561197984468488","76561197984468488","76561197984468488","7656119798,[75,[5286.79,11151.6,0.00146132]],8221,"213"]"
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 "CHILD:102:213:"
 9:45:15 "LOAD CHARACTER: \cache\players\7\76561197984468488-char.sqf"
 9:45:15 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0,0],0,[7.1,17.4801]],[0,0,0,0],["M9","aidlpercmstpsraswpstdnon_player_idlesteady01",42,["76561197984468488","76561197984468488","76561197984468488","7656119798,[75,[5286.79,11151.6,0.00146132]],8221,"213"]"
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 "CHILD:102:213:"
 9:45:15 "LOAD CHARACTER: \cache\players\7\76561197984468488-char.sqf"
 9:45:15 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0,0],0,[7.1,17.4801]],[0,0,0,0],["M9","aidlpercmstpsraswpstdnon_player_idlesteady01",42,["76561197984468488","76561197984468488","76561197984468488","7656119798,[75,[5286.79,11151.6,0.00146132]],8221,"213"]"
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 Error in expression <[75,[5286.79,11151.6,0.00146132]],8221,"213"]>
 9:45:15   Error position: <213"]>
 9:45:15   Error Missing ]
 9:45:15 "_characterID: any"
 9:45:15 "CHILD:201:214:[125,[5217.56,6178.3,1.54464]]:[["ItemFlashlight","ItemHatchet_DZE","ItemMap","ItemRadio","ItemToolbox","UZI_SD_EP1","ItemMatchbox_DZE","ItemCrowbar","AK_107_pso"],["ItemPainkiller","ItemBriefcase100oz","ItemGoldBar5oz","ItemGoldBar5oz","30Rnd_545x39_AK","30Rnd_545x39_AK","ItemGoldBar5oz","ItemMorphine","ItemGoldBar5oz","ItemBriefcase30oz","ItemBandage","ItemBandage",["30Rnd_9x19_UZI_SD",11],"30Rnd_9x19_UZI_SD","ItemBandage","30Rnd_9x19_UZI_SD","30Rnd_9x19_UZI_SD"]]:["DZ_CivilBackpack_EP1",[["M110_NVG_EP1","Mk_48_DZ"],[1,1]],[["FoodCanBakedBeans","30Rnd_9x19_UZI_SD","ItemWaterbottleBoiled","FoodSteakCooked","ItemSodaCoke","ItemPainkiller","5Rnd_86x70_L115A1","ItemBloodbag","ItemAntibiotic","ItemMorphine","ItemGoldBar5oz"],[1,1,1,1,1,1,1,2,2,1,4]]]:[false,false,false,false,false,false,true,12000,[],[0,0],0,[17.89,16.275]]:false:false:2:2:3:0:["UZI_SD_EP1","amovpknlmstpslowwpstdnon_gear_amovpknlmstpsraswpstdnon",42,[]]:0:0::10:"
 9:45:20 "CHILD:201:126:[220,[4730.79,12547.3,0.00142432]]:[["Binocular_Vector","NVGoggles","ItemMap","ItemToolbox","ItemRadio","ItemCompass","ItemHatchet_DZE","ItemCrowbar","ItemMachete","ItemEtool","ItemKnife","ItemGPS","ItemMatchbox_DZE","Mk_48_DZ"],[["100Rnd_762x51_M240",94],"100Rnd_762x51_M240","cinder_wall_kit","cinder_wall_kit","cinder_wall_kit","CinderBlocks","CinderBlocks","CinderBlocks","CinderBlocks","MortarBucket","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage"]]:["DZ_LargeGunBag_EP1",[[],[]],[["MortarBucket","CinderBlocks"],[9,18]]]:[false,false,false,false,false,false,true,12000,[],[0,0],0,[171.275,108.943]]:false:false:0:0:9:0:["Mk_48_DZ","amovpercmstpsraswrfldnon_gear",41,["76561198034065410","76561198034065410"]]:0:0::0:"
 9:45:29 "CHILD:201:126:[225,[4731.09,12544.9,0.00153257]]:[["Binocular_Vector","NVGoggles","ItemMap","ItemToolbox","ItemRadio","ItemCompass","ItemHatchet_DZE","ItemCrowbar","ItemMachete","ItemEtool","ItemKnife","ItemGPS","ItemMatchbox_DZE","Mk_48_DZ"],[["100Rnd_762x51_M240",94],"100Rnd_762x51_M240","cinder_wall_kit","cinder_wall_kit","cinder_wall_kit","CinderBlocks","CinderBlocks","CinderBlocks","CinderBlocks","MortarBucket","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage","ItemBandage"]]:["DZ_LargeGunBag_EP1",[[],[]],[["MortarBucket","CinderBlocks"],[9,18]]]:[false,false,false,false,false,false,true,12000,[],[0,0],0,[171.275,108.943]]:false:false:0:0:2:1:["Mk_48_DZ","amovpercmstpsraswrfldnon_gear",41,["76561198034065410","76561198034065410"]]:0:0::0:"
 9:45:33 "infiSTAR.de PlayerDisconnected: _uid: 76561197984468488   _name: 3ºSgt.Edu"
 9:45:33 "get: STRING (76561197984468488), sent: STRING (76561197984468488)"
 9:45:33 "DISCONNECT: 3ºSgt.Edu (76561197984468488) Object: B 1-1-D:1 (3ºSgt.Edu) REMOTE, _characterID: any at loc [6463.5,-1989.5,1.14464]"
 9:45:33 "ERROR: Cannot Sync Character 3ºSgt.Edu has nil characterID"
 9:45:33 "CHILD:204:76561197984468488:"
 9:45:33 Player 3ºSgt.Edu disconnected.
 9:45:33 Client: Remote object 6:3 not found
 9:45:33 Client: Remote object 6:2 not found
 9:45:33 Client: Remote object 6:0 not found
 9:45:33 "CHILD:103:76561197984468488:any:2:"
Found differences
 
my file:
on line 55
_key = format["\cache\players\%1\%2.sqf", (MyPlayerCounter - 1), toLower(_playerID)];
and line 64
_primary = ["PASS",false,"1",[],[["ItemFlashlight","ItemMap","ItemGPS"],["ItemBandage"]],["DZ_Patrol_Pack_EP1",[],[]],[0,0,0],"Survivor2_DZ",0.96];

 

uploaded file:
on line 55
_key = format["\cache\players\%1\%2.sqf", (MyPlayerCounter-1), toLower(_playerID)];
and line 64
_primary = ["PASS",false,"1",[],[["ItemFlashlight","ItemMap","ItemGPS"],["ItemBandage"]],["DZ_Patrol_Pack_EP1",[],[]],[0,0,0],"Survivor2_DZ",0.96,0];

I'm hoping this solves the problem.

Thank you very much!

Link to comment
Share on other sites

I have not witnessed more problems until this moment.
After making changes, I run this command to reset all info of players database
UPDATE character_data SET Alive = 0;
That's because I do not know exactly how many players are leaving to play on the server prevented by this problem. Then I manually changing Alive = 1 for players who were newer on the server and were ok.
 
So far, it's all going well.
Thank-you very much for this help!
Link to comment
Share on other sites

To me it looks like your cache folder is broken,

16:42:25 "LOAD CHARACTER: \cache\players\12\76561198119009356-char.sqf"
16:42:25 "CHARACTER CACHE: ["PASS",[false,false,false,false,false,false,false,12000,[],[0.495822,0],0,[5.7,3.03333]],[13,12,0,8],["UZI_SD_EP1","aidlpknlmstpsraswpstdnon_player_0s",42,["76561198119009356","76561198119009356","76561198119009356","765611981190,[309,[1930.88,11992.5,0.582269]],3535,"20"]"
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]],3535,"20"]>
16:42:25   Error position: <20"]>
16:42:25   Error Missing ]
16:42:25 Error in expression <,[309,[1930.88,11992.5,0.582269]]

Its missing a Close bracket at the end of "20" and a " at the end of the last player id

 

 

did you try clearing the player folder? 

Link to comment
Share on other sites

Hello Guys,
 
My cache folder looks ok
 
The problem persists though, I realized that can be solved only by clearing the table CurrentState in player database.
 
Analyzing the information of players affected by this bug, I realized that in CurrentState table lacked a "]" and that contains information that does not seem to be useful for this. I also realized that this field is not essential and with this, I created a simple, temporary solution via cron that is to run a command to clear this table of 1 in 1 minute. So if a player has problems, it can aguadar 1 min and reconnect it will succeed.
 
I know it was not the right solution but it is the simplest.
 
In my cron defines i add this:
* * * * * /path/of/server/dayz_epoch/fix_bug.sh

and my fix_bug.sh bash script:

#!/bin/bash

/usr/bin/mysql -u mysqluser --password=mypass dayz_linux -e "UPDATE character_data SET CurrentState = '[]';"
Link to comment
Share on other sites

I don't know...this is just a workaround. You have another problem. This is not a bug where a bug fix is needed. That happens only to you for whatever reason.

But you said you did everything manually...so there is always a lot of space for errors ;)

 

I mean: post if you want whatever you have: the default player, charactzer.sqf file in the cache dir. A real players files from there. Maybe your writer.pl (the new one).

 

It's much easier to help if you can see something.

Link to comment
Share on other sites

The writer.pl & server_playerLogin.sqf were replaced by those who were posted here. That is, the problem is elsewhere, I believe it is a failure in reading the information shown in the server console but why this is happening i do not know.

Now, i have at a temporary solution to this problem can look over time

Link to comment
Share on other sites

The temporary solution was that I mentioned above ... (clear the table CurrentState)
UPDATE character_data SET CurrentState = '[]';

Now created a system to monitor this bug, it works well.

I created a script in bash called agent.sh with the following routine
#!/bin/bash

while read line
do
  if [[ "Error Missing ]" == `echo "$line" | grep -o "Error Missing ]"` ]]; then
     /usr/bin/mysql -u dayz_userDB --password=myDBpass dayz_database -e "UPDATE character_data SET CurrentState = '[]';"
  else
     echo "$line"
  fi
done <&0

this script is cerregado and works the same way as the writer.pl attached to epoch.sh, it line by line looking at the console for the error "Error Missing ]" and when found, it clears the table "CurrentState" and epoch.sh, looked like this:

/usr/bin/mysql -u dayz_userDB --password=myDBpass dayz_database -e "UPDATE character_data SET CurrentState = '[]';"
export LD_LIBRARY_PATH=.:/usr/lib32:$LD_LIBRARY_PATH;./server -server -mod="@dayz_epoch;@dayz_epoch_server;" -config="cfgdayz/server.cfg" -cfg="cfgdayz/basic.cfg" -port=2302 -beta="expansion/beta;expansion/beta/expansion" -noSound -noPause -world=Takistan -profiles=cfgdayz -name=cfgdayz -cpucount=2 -showscripterrors -pid=2302.pid 2>&1 | ./writer.pl 2>&1 | ./agent.sh

In green my changes

Note that so, clean the table CurrentState whenever the server is started and wherever you see the error "Error Missing ]"

 

The only problem is that the player does not return to the exact state it was as crouched, lying down or with primary weapon in hand. It always comes back up and the secondary weapon in hand, but it's better that he not be able to play  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...