EpochModTeam / DayZ-Epoch

Experimental DayZ Mod for Arma 2
http://epochmodteam.github.io/DayZ-Epoch
226 stars 399 forks source link

1.0.6 RC1 Testing Bugs/Issues #1712

Closed icomrade closed 8 years ago

icomrade commented 8 years ago

Post all issues pertaining to the first release candidate of the Epoch 1.0.6 update here.

Known issues from the previous topic:

DO NOT run test buils with infistar or other mods that are not updated to work with 1.0.6. You MUST use the new HiveExt.DLL if you are running a server, the new dll requires visual c++ redistributable 2015.

ndavalos commented 8 years ago

Snap building doesn't snap properly, at least on metal floors, they snap slightly below where they should have: http://images.akamai.steamusercontent.com/ugc/262717416883152107/0659F4D2AB5A634328A759D9A07C6B09058AFE84/

ndavalos commented 8 years ago

So I converted/upgraded an existing database and there seems to be a problem with the order things are getting spawned in, or gravity or something. If you have helicopters sitting on metal floors they have a tendency to explode or fall through the metal floors (or the floors haven't been created yet).

This is what happens right after a server restart and the first player logs in: http://images.akamai.steamusercontent.com/ugc/262717416883168080/792D5168BAF57F9F4135B05562EFDF3A953596BD/

This is what it would have looked like under normal conditions: http://images.akamai.steamusercontent.com/ugc/262717416883183084/D979A78D1805D6EFE83625C68289F4BF2AF16106/

icomrade commented 8 years ago

@ndavalos try commenting out line 254 in server_monitor.sqf: _object setVelocity [0,0,1]; repacking your dayz_server.pbo and reloading the server. This may be the reason vehicles are falling before buildables load

ndavalos commented 8 years ago

@icomrade that sort of fixed it, this is the end result: http://images.akamai.steamusercontent.com/ugc/262717416883351903/6C36FF6D8101A13404356A87ACFB8FE6BFAC49C4/

The helis in the air are normally sitting on the floors, haven't moved them in months lol.

I can provide you with a database if you want to play with it, well maybe not lol, all my objects still have coins in the inventory, I had to change the inventory function in server_monitor.sqf to handle that.

icomrade commented 8 years ago

Well that's interesting, they should load in exactly when the DB has them saved. The database would be helpful for this so if you can provide it that would be appreciated. I'm in the epoch discord if you want to send it to me there, or PM me on the epoch forums http://epochmod.com/forum/profile/11576-icomrade/

icomrade commented 8 years ago

@ndavalos Alright, ifor you're planning on doing that base your new Dll on this repo: https://github.com/icomrade/DayZhiveEpoch if you want to merge in your changes I can add you as a collaborator so they get added to the pull request at the original repo which mine was forked from

ndavalos commented 8 years ago

@icomrade lol unfortunately I don't do c, I probably should have learned it at some point, maybe on day...I work in Delphi (pascal) professionally, so that's what it'll be written in :)

ndavalos commented 8 years ago

@icomrade so after experimenting with spawning in vehicles, this sort of solves the problem with things blowing up when spawned, and sets their proper location. It also spawns vehicles in faster: _object = createVehicle [_type, [0,0,0], [], 0, if (_type in DayZ_nonCollide) then {"NONE"} else {"CAN_COLLIDE"}]; _object allowDamage false; _object enableSimulation false; _object setPos _pos; _object setDir _dir; _object allowDamage true; _object enableSimulation true;

This was just experimenting though. createvehicle with position [0,0,0] is actually faster than specifying the position when creating it, then do a setdir/setpos after. Only problem is things spawned in on pitched terrain don't sit on the terrain lol. So if a vehicle is on a hill it will be level instead of having it actually resting on the terrain, I'm sure it has to do with the enablesimulation I put in. If I take that out, they sit on the ground properly. Using this method also had very little in the way of destroyed vehicles after spawning in. I think only 4 of them blew up. Also note, the m240 nets at the base in the cave all appeared where they're supposed to be placed after using this method.

It still caused a couple helis to explode that were on metal floors, but something to look at if you're going to look at that issue. It was merlins that blew up @003131 in the database I provided you.

icomrade commented 8 years ago

SetVelocity is used to sit the vehicle on the ground properly, it initializes physics after spawn in. That's why after you commented that line out some vehicles were floating in the air. I'm more concerned as to why you have some vehicles spawning in 10 feet above the platform they were landed on. There may be some inconsistencies between saving and spawning vehicles.

ndavalos commented 8 years ago

@icomrade I'm not sure if they're spawning in with CAN_COLLIDE, or not, didn't bother logging that. If they are, then yeah they should go exactly where you put them, if not then the engine will adjust things.

Edit: as a side note, I did setpos myself where one of the merlins was in the db and it was exact. I'll have to do that with one of the floaters.

ndavalos commented 8 years ago

@icomrade so I wrote my own function in a dll to load up the list of objects to spawn. Takes 1-2 seconds for it to load the array, but I'm not sure if you would even want to do this since it is very unconventional. I'm basically opening a query in the dll with the first call and deleting the previous copy of the sqf generated, the second call tells it to create an sqf in the arma directory then has the engine execute that file.

server_loadobjectscript = {
    private["_key","_resultArray","_data"];
    _key = _this;
    _data = "dpfunctions" callExtension _key;
    _resultArray = call compile _data;
    diag_log format["start load: %1",diag_ticktime];
    call compile preprocessFileLineNumbers format['\objectspawn\object%1.sqf',DZ_Server_Instance];
    diag_log format["end load: %1",diag_ticktime];
    _resultArray
};

The contents of the file look something like this:

DZ_Object_Array = [];
_myArray = ["OBJ","60668","LockboxStorageLocked","10289",[233.257,[291.606,2181.45,0]],[[[],[]],[["Machete_Swing","ItemBriefcase100oz","ItemBriefcase70oz","ItemGoldBar3oz","ItemBriefcaseS80oz","ItemSilverBar7oz","ItemBriefcaseS90oz","ItemSilverBar6oz","ItemGoldBar6oz"],[1,9,1,1,1,1,1,1,1]],[["DZ_LargeGunBag_EP1"],[1]]],[],0,0,0];DZ_Object_Array set [count DZ_Object_Array, _myArray];

It's very unconventional, but it prevents repeated calls to a dll, and is extremely fast. Something to think about I guess. It also overcomes the 4096 byte boundary for returning data.

I looked at the code in hive and it appears to be doing some stuff that you could actually just schedule an event on the database to handle every night or whatever. The fixing uids I actually have an event scheduled to do that:

delimiter //
CREATE EVENT `fix_objectuids`
    ON SCHEDULE
        EVERY 1 DAY STARTS '2016-03-27 01:00:00'
    ON COMPLETION NOT PRESERVE
    ENABLE
    COMMENT ''
    DO BEGIN
update object_data set objectuid = objectuid + objectid where objectuid in (
select distinct objectuid from (
select objectuid, count(*) from object_data group by objectuid having count(*) > 1) t1);
END
//
delimiter ;

Not sure what to tell you about the increase of time though, populateObjects should do as little as possible. You may consider moving most of the code in there that doesn't involve returning objects to a separate function. When arma loads an extension, that extension stays in memory, so anything that is in memory for the dll will remain. For instance, if you open a query object, that object retains it data and state until the arma server process actually exits. At no point does arma unload the dll.

The method I worked out was:

  1. Call extension, tell it to open a query with a list of everything from object_data - exit the function.
  2. Call extension, tell it to load the array with the previously loaded query, close the query - exit the function.
  3. Start spawning items.

I think part of the problem is you're opening and executing queries for every single record in object_data from server_monitor. That's a lot of overhead, especially when you are hitting mysql 7k times. I would suggest the first call to hive where it gets the object count should execute all that extra code you have in populateObjects, then populateObjects simply returns objects and whatever REALLY needs to be done while doing that. You'll have to evaluate what is absolutely essential for populateObjects to do.

icomrade commented 8 years ago

The hiveExt already loads everything in one query and iterates through the elements to ensure the data is valid and builds an array of objects to send to the server to spawn in SQF. I think the ObjID Fix is best executed sever restart, but in reality I suppose it doesn't really need to be, but I don't know if the overhead of this is noticeable. On another note using code blocks is helpful, surround your code with 3 back ticks: ```

auto worldObjsRes = getDB()->queryParams("SELECT `ObjectID`, `Classname`, `CharacterID`, `Worldspace`, `Inventory`, `Hitpoints`, `Fuel`, `Damage`, `StorageCoins` FROM `%s` WHERE `Instance`=%d AND `Classname` IS NOT NULL", _objTableName.c_str(), serverId);
    if (!worldObjsRes)
    {
        _logger.error("Failed to fetch objects from database");
        return;
    }
    while (worldObjsRes->fetchRow())
    {
    ...

All of the objects/strings/pointers etc. should be destroyed and removed from memory once the initial load of the object_data table is done. I'm not sure why it wouldn't be cleaned up by the compiler since once populateObjects finishes everything referenced is no longer in scope and similarly so with streamObjects. I may be missing something, plus I'm not all that experienced with C++ so I probably wouldn't be able to identify the problem.

Also I think the biggest issue with increased load time is the modified servermonitor file, I noticed whether the DB was new, empty or populated the minimum load time is ~30 seconds. We definitely need to look into performance optimization.

ndavalos commented 8 years ago

@icomrade In server_monitor it does this:

if (_status == "ObjectStreamStart") then {
    _hiveLoaded = true;
    _val = _result select 1;
    //Stream Objects
    diag_log ("HIVE: Commence Object Streaming...");
    for "_i" from 1 to _val do {
        _result = _key call server_hiveReadWriteLarge;
        _status = _result select 0;
        _myArray set [count _myArray,_result];
    };
    diag_log ("HIVE: Streamed " + str(_val) + " objects");

Which, I don't do c++, but from reading the code it appears to open a query each call:

    auto worldObjsRes = getDB()->queryParams("SELECT `ObjectID`, `Classname`, `CharacterID`, `Worldspace`, `Inventory`, `Hitpoints`, `Fuel`, `Damage`, `StorageCoins` FROM `%s` WHERE `Instance`=%d AND `Classname` IS NOT NULL", _objTableName.c_str(), serverId);
    if (!worldObjsRes)
    {
        _logger.error("Failed to fetch objects from database");
        return;
    }

But again, I don't do c++ so I could be misinterpreting that in populateObjects as executing the query each call, or misinterpreting what server_monitor is doing in relation to calling the dll.

The rest of server_monitor is taking too long as well. The script is getting suspended during execution causing it to take around 80 seconds to spawn in 7k. There's some stuff that could probably be done to fix it completely. @eraser1 mentioned maybe moving to an fsm to spawn things in unscheduled and control the entire process better.

ndavalos commented 8 years ago

@icomrade also, change the query to load the objects to only get those with damage < 1 to reduce the object count instead of having to evaluate it in sqf.

icomrade commented 8 years ago

That SQL query is only executed once, I think the subsequent calls of child 302 return a single object. once the initial load of the object_data table _srvObjects is no longer empty so it should go to the else condition.

https://github.com/icomrade/DayZhiveEpoch/blob/master/Hive/Source/HiveLib/HiveExtApp.cpp#L300-L343

I have a server_monitor.sqf that I was testing that uses spawn and tries to create vehicles in multiple threads in parallel. I still have to tweak it, but on average it saves ~10 seconds with 4000 objects in the DB.

Edit: I do agree there is a lot of overhead with this method but I believe there is a limit with the amount of data callExtension can return as mentioned here: https://github.com/EpochModTeam/DayZ-Epoch/issues/1197 So I don't know if this is going to be an issue with returning everything in one array.

eraser1 commented 8 years ago

I have a server_monitor.sqf that I was testing that uses spawn and tries to create vehicles in multiple threads in parallel. I still have to tweak it, but on average it saves ~10 seconds with 4000 objects in the DB.

SQF threads never really run "parallel", only a single statement of SQF is ever executed in any given instant. It appears to be saving time either because of lots of other SQF "threads" that have been spawned from other scripts, thereby artificially increasing the priority of object spawning, simply by the presence of more threads, or you simply measured the time of completion of the server_monitor code, which doesn't measure the actual time taken to spawn the objects.

ndavalos commented 8 years ago

I just managed to spawn in 7k+ objects in 30 seconds and set all the properties on them after the fact in 20 with the method I developed last night. I changed my methodology to create an sqf to load up the object array with actual objects and create them. After the engine runs it, it signals the clients that login is ok and spawns a thread to update all the properties on the objects like damage, hitpoints, inventory etc.

ndavalos commented 8 years ago

@icomrade some suggestions for optimizing:

  1. setVariable public only if the clients need the data, this reduces execution times tremendously. You're not broadcasting everything that is unnecessary to the clients.
  2. Only execute exactly what is needed for players to actually start playing right away, skip all the mess that can be handled after players have logged in. As long as the object has been created, codes added and inventory added, you're good. Damage, adding to object monitoring arrays, etc can all take place after the fact. All of that stuff will only take maybe 30 seconds to execute on all the objects once clients are connected.

As @eraser1 suggested, using an fsm to create the objects probably will significantly lower the cost of spawning everything in. My new method (not the fsm) takes anywhere from 40-60 seconds to spawn everything and add inventory as opposed to 2 minutes.

icomrade commented 8 years ago

Between a well written server_monitor.sqf and a well written FSM version I doubt there will be a meaningful difference. Rewriting the whole server startup process as an fsm may be more beneficial but since server_monitor.sqf is relatively simple in its condition checking there may not be a huge benefit. Even just moving simple things to the HiveEXT like typename checks will probably offer more performance benefit than moving to an fsm.

eraser1 commented 8 years ago

That is actually my point. Running the entire server startup sequence unscheduled could make a very significant difference.

Also, not just the server startup sequence, but I also found that running the player login system helped with player login times significantly under load.

ndavalos commented 8 years ago

I did some profiling of the various functions of server_monitor and the engine was pausing the script anywhere from 20ms to 100ms randomly while setting up objects. Some objects would create and update in 1ms, some 20ms and some 100ms. So running scheduled is going to have some issues, especially when you have around 6 or 7k objects.

icomrade commented 8 years ago

A couple of observations on the server_monitor performance. changing server_monitor to call compile instead of execVM decreases the total callExetension time for the HiveEXT by 5x (3s vs 15s for 4100 items). I believe the max number of loop iterations in a called environment is 10,000 so it's probably not an appropriate change.

I've moved some stuff and changed some stuff and was able to shave some time off load in, but it's still far from where it should be. with 4100 objects the } forEach _myArray; loop takes ~200 seconds still.

ndavalos commented 8 years ago

@icomrade few suggestions:

  1. The setting coins evaluation should be DZE_MoneyStorageClasses + locked storage. DZE_MoneyStorageClasses is used in fn_selfactions, so having it allow access to a safe's coins while locked is no good :P
  2. While it takes a little bit longer later on, you can do the enablesimulation and setvelocity on vehicles after clients are allowed to log in.
  3. Use CAN_COLLIDE for all createvehicle. Using NONE does not enable any sort of physics, enablesimulation and setvelocity does. The only thing you're doing with that is telling the engine to calculate the nearest empty position if an object intersects something else when calling createvehicle.
  4. You can probably do inventory after clients can log in, it will only take maybe 10 seconds to update inventory on everything after the fact.
  5. Use spawn for all other updates after creating the objects. When you create them, setvariable anything that you normally would use to do updates on objects then read that back out into the variables you use for other code when you spawn a thread for it. For an example _object setvariable["_inventory",false]; Then when you get around to setting inventory (hitpoints whatever) do _inventory getVariable["_inventory",[]]; Pass your object array into each of the spawned code.
  6. Figure out what really needs to get broadcast on setVariable, when you broadcast this causes quite a bit of overhead in the engine.
  7. Consider having hive write out a file of objects like I had mentioned. It makes hive take 2-3 seconds to dump the database and for the server to load up the object array. Don't write to the file every record in the query, fill up a string list (not sure what the equivalent in c++ is) then write it all at once to disk. In delphi, I basically create a stringlist object, add the stuff to it, then call savetofile on the stringlist after it's done loading it. This avoids the overhead of repeatedly re-entering the dll.

OR use an fsm :P Figure out what is critical for clients to log in and do that first, do the rest after you let clients log in. If you log the tick time for every part of object creation, you'll see the main reason everything takes so long is because the engine is suspending the thread anywhere from 20-100ms while server_monitor is doing it's thing. This is killer when you have a large number of objects. The reason each iteration through the object array is taking 200 seconds is the engine suspending the thread.

Pretty much every millisecond counts to getting the server ready for clients.

eraser1 commented 8 years ago

I believe the max number of loop iterations in a called environment is 10,000~~

This only applies to while loops, not "forEach" or "for" loops.

ndavalos commented 8 years ago

@icomrade got 7k objects read in and spawned in 17 seconds using my method.

icomrade commented 8 years ago

@ndavalos is there anything you've done that is different than the current server_monitor. If you've changed something reply with a link that points to the line number and file

ndavalos commented 8 years ago

@icomrade I practically rewrote server_monitor, but some of the optimizations I've done are:

  1. https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_server/system/server_monitor.sqf#L155 Is now: _object = createVehicle [_type, [0,0,0], [], 0, "CAN_COLLIDE"];
  2. https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_server/system/server_monitor.sqf#L172 Is now: if (_storageMoney > 0) then {_object setVariable [Z_BankMoneyVariable, _storageMoney, true];};
  3. https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_server/system/server_monitor.sqf#L203 Is now: _cargo = _inventory; if (_storageMoney > 0) then {_object setVariable [Z_BankMoneyVariable, _storageMoney, true];}; //diag_log format["%1, %2",_object,_cargo]; _weaponcargo = _inventory select 0 select 0; _magcargo = _inventory select 1 select 0; _backpackcargo = _inventory select 2 select 0;

           _weaponqty = _inventory select 0 select 1;
           {_object addWeaponCargoGlobal [_x, _weaponqty select _foreachindex];} foreach _weaponcargo;
    
           _magqty = _inventory select 1 select 1;
           {_object addMagazineCargoGlobal [_x, _magqty select _foreachindex];} foreach _magcargo;
    
           _backpackqty = _inventory select 2 select 1;
           {_object addBackpackCargoGlobal [_x, _backpackqty select _foreachindex];} foreach _backpackcargo;

You'll also need to add: if (_storageMoney > 0) then {_object setVariable [Z_BankMoneyVariable, _storageMoney, true];}; To the locked storage inventory spot: https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_server/system/server_monitor.sqf#L190 Because you can't have locked storage in the DZE_MoneyStorageClasses array due to it's usage in fn_selfActions

ndavalos commented 8 years ago

Curious if it would be possible to fix the models for safes, depending on the lighting conditions you end up with transparent safes: http://images.akamai.steamusercontent.com/ugc/1617176672223319624/FAF311342D8CFE63CCD4B6C3EC175EBC37D10531/

oiad commented 8 years ago

I believe that is to do with your graphics settings, when you have ATOC turned on it will do this. Door frames/cinder doors also become see through

ndavalos commented 8 years ago

@oiad you're right, as long as the setting does not include grass it's fine. So basically just trees.

AirwavesMan commented 8 years ago

Normal SUVs have extremely strong armor and glasses. If you dont shoot on the engine it is really hard to destroy that vehicle. If you shoot the side from the SUV it takes very low damage. I think this is not the intention.

icomrade commented 8 years ago

I think SUVs are fairly weak in contrast to other vehicles, I don't think anyone really has an issue with the amount of armor. I mean they are technically utility vehicles, I'd expect them to be stronger than a regular car.

AirwavesMan commented 8 years ago

@icomrade Did you check the SUVs ingame? I cant destroy an SUV with 4 AK74 mags if I shoot only on the right or left side of the vehicle. The SUV is like an HMMWV right now.

icomrade commented 8 years ago

Ak74 is 5.56 it's a very weak gun, 5.56 is very weak in Arma 3 also, and is weak against players as well so I wouldn't expect it to destroy a vehicle quickly. Honestly I don't think there's anything wrong with the sun, if your looking to destroy a vehicle use an appropriate weapon like a 7.62 gun or lmg

AirwavesMan commented 8 years ago

Tested now with M240. After 5 mags in the left side the SUV did not blow up. A HMMWV blows up after 3 mags. So basically you have to hit the SUV directly on the front engine. Am I totally wrong here or is a bit too much? Perhaps Im just too familiar with the old epoch vehicles and it seems only for me too much.

icomrade commented 8 years ago

Armor of the SUV is 25 unless you are using an upgraded SUV (armor upgrade gives 60 armor), the HMMV is 40. if the SUV doesn't get damaged from the side I don't think it's something that can be fixed from the configs, the model itself would need to have the engine hit points modified.

ndavalos commented 8 years ago

@icomrade this file: https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_code/system/scheduler/sched_spawnCheck.sqf Has this code:

#include "scheduler.hpp"

sched_spawnCheck_init = { []spawn{} };
sched_spawnCheck = {
    HIDE_FSM_VARS
    if (scriptDone _this) then {
        _this = [] execVM '\z\addons\dayz_code\compile\player_spawnCheck.sqf';  // stuffed with "sleep" commands, can't put it in scheduler
    };
    _this;
};

but that is defined as a variable in compiles: player_spawnCheck = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_spawnCheck.sqf";

Is there any way of making that use what's defined in compiles instead? I need to override this function, but by doing it this way, I can't without overriding a bunch of other stuff as it currently stands just to get to this one function.

icomrade commented 8 years ago

you'll need to edit sched_init.sqf or create a folder of the structure exactly replicating the path of _base (in sched_init.sqf) and place your custom sched_spawnCheck.sqf in it. so it would be [Mission root]\z\addons\dayz_code\system\scheduler\sched_spawnCheck.sqf. you will also need to overwrite player_spawnCheck

ndavalos commented 8 years ago

@icomrade I was hoping it could just be changed to

sched_spawnCheck_init = { []spawn{} };
sched_spawnCheck = {
HIDE_FSM_VARS
if (scriptDone _this) then {
_this = [] spawn player_spawnCheck '; // stuffed with "sleep" commands, can't put it in scheduler
};
_this;
};

Since player_spawnCheck is defined in compiles already, makes it much simpler to override the function without having to replicate the scheduler.

I'm basically adding 1 line to that file to do an extra check for plot poles and safezones to prevent loot and zombies from spawning within plot pole radius (or safezone radius).

If it's not a good idea due to spawn adding a new scheduled environment then that's ok and I'll just replicate the scheduler, unless of course you feel like adding one thing to spawncheck to check to see if a variable is defined and executing the code in the variable for additional checks people can add without having to override the code.

Something like:

if !(isNil "DZE_ExtraSpawnCheck") then {
_doNothing = _position call check_spawning_distance;
};

if (_doNothing) exitwith {};
ndavalos commented 8 years ago

@ebaydayz Well, execvm adds a thread to the main scheduled environment, spawn creates a new thread and scheduled environment (that runs alongside the main scheduled environment). That's really the difference between the two (aside from calling convention and error reporting). I don't really see a problem with that one being spawned, hell it might even improve it's performance instead of stacking it in the main scheduled environment. Either way I can deal with it, just tossing out some suggestions since it's already compiled in compiles as a variable, but that variable isn't being referenced anywhere in the mod. The other alternative would be good too, or some variation thereof. I wouldn't mind having that one little thing in there (however it's implemented) to allow for additional checks on whether or not to run the spawning code. That way I'm not overriding an entire file to add 1 line of code :)

icomrade commented 8 years ago

You don't have to replicate the scheduler, I don't think I let on that you have to recreate the folder structure. Same concept behind the BIS Init error fix I added to the missions, since the path in https://github.com/EpochModTeam/DayZ-Epoch/blob/master/SQF/dayz_code/system/scheduler/sched_init.sqf doesn't have a preceeding \ it can be overwritten by a file in the mission. Also look at the referenced file to see why just overwriting only the compile won't work.

ndavalos commented 8 years ago

@icomrade Ah, I see the missing "\" at the beginning of the base path. I would however prefer not to override any code if at all possible. It's just a pain to deal with, so I try and avoid it, especially for a 1 line change.

@ebaydayz I believe I was basing my assumption about scheduled environment based on the comments on spawn in the wiki.

icomrade commented 8 years ago

Honestly it's not a big deal, adding a replication of the file vs overwriting the compile is a difference of 2 lines of code in this case.

ndavalos commented 8 years ago

@icomrade actually what I was referring to is second option of adding something to player spawn check instead of having to override anything. That way if there's a base change in the mod, there's no need to try and keep things in sync

So in player_spawncheck.sqf something like:

if !(isNil "DZE_ExtraSpawnCheck") then {
_doNothing = [_position, _spawnableObjects, _speed, _radius, _spawnZedRadius, _maxlocalspawned, _maxControlledZombies, _maxWeaponHolders, _currentWeaponHolders, _inVehicle] call DZE_ExtraSpawnCheck; //return result is assigned to _doNothing
};

if (_doNothing) exitwith {};
icomrade commented 8 years ago

I modified the Hive to write to a file and have the server read form it, eliminating the need for callExtension nested in a loop. The file is named uniquely per startup based on the init key and is placed in the A2 root directory. Unfortunately I cannot truncate or delete the file until the next restart since OA locks the file once it is read by the engine. I'm concerned that this is a security issue as there's essentially a plain text DB dump of the objectData table sitting in the OA directory. I'm curious if anyone knows of a way to unlock the file once it's loaded by OA, or even write to the file using in sqf. #include, preprocessfile, loadfile all lock the file, htmlLoad won't work since the dedicated has no display, if there's a non-locking way to read a file I'd love to know of it.

On a performance note this only saves 2-3 seconds with 7000 objects, but it will fix https://github.com/EpochModTeam/DayZ-Epoch/issues/1197 if this was the issue (I feel it's unlikely).

ndavalos commented 8 years ago

Nah there's really no way to unlock the file. I'm leaving them with the same name and deleting them in the dll before writing a new one on restart. Most people run their db on the same machine, so there's really no difference, they'd have the credentials for the db anyways since you don't encrypt them in the hive.ini file. I use a specific folder for the file, not the root, you can load from a specific directory just using "\mydir\myfile.sqf" . I'm getting a consistent 20-30 second startup with my server_monitor and dll, hive gives me about 75 seconds + so I think your problem is elsewhere not the iterations if hive only takes a few seconds normally now.

icomrade commented 8 years ago

I didn't expect a huge performance increase since the loop only took a couple seconds to complete anyway. I'm curious as to why there's such disparity in the load times experienced with the 2 versions of the server_monitor file. Looking at the server_monitor you sent me a while ago, you removed all the worldspace crap which I've been looking to do for a while and you've also removed that config lookup which is intensive, also a lot is missing so I assume the rest is handled elsewhere. I don't think moving the networked commands (setvariable) to a spawn is making a difference since I completely commented them out with no meaningful difference.

Also, did I assume you tested with the server_monitor I committed yesterday, it should be quite a bit better than previous versions.

AirwavesMan commented 8 years ago

When the Hrotor from a heli is to 100% damaged the chopper can still fly. This is an old epoch bug perhaps an arma bug? Can we fix that?

ndavalos commented 8 years ago

@icomrade just tested the new server_monitor etc. Loads you in within a minute with 7.5k objects. I got a retrying authentication though at some point, not sure what that was about. Otherwise it's loading fairly well.

client.txt

arma2oaservertest.txt

AirwavesMan commented 8 years ago

I remember two old epoch or arma2 bugs. Im not sure from which it comes.

When someone eject from a flying little bird, the little bird gets heavyle or fully damaged.

Switching between the gunners in a flying chopper can result in ejecting from the chopper without a parachut. E.g. When you are on the left gun from a UH1H and you switch to the right gun there is a chance that you just fall out of the chopper without a parachut. Tested with UH1H and Mi17.