Author Topic: Dedicated Server Autosave Script  (Read 1393 times)

I run a dedicated server for The Building Association clan and I need help trying to setup a script that will allow me to set the server to AutoSave every 15 minutes or so.

I found this code snippet while searching the forums for a solution:

Code: [Select]
function AutoSave()
{
savebuild("AUTOSAVE");
$AutoSave = schedule(900000,0,AutoSave);
}

I wrapped it up into its own server.cs and packaged it in a .zip with a description.txt file. I then loaded it onto the dedicated server via the Add-Ons option under Start Game (then quit out of BL and started the dedicated server.) However, I cannot call the command from the console when I am in the server. It just keeps telling me Invalid Function (or something similar). I guess I have a couple questions.

(1) Is an autosave function on the server-side possible?
(2) Is the code above OK? Have any more experienced BL scriptwriters written a better script that can take care of this problem?
(3) What am I doing wrong (or am I doing everything wrong?), and what can I do to fix the problem so it works?

Thank to anyone who can help.

Look around at this.
Code: [Select]
function dediSave(%name, %desc, %events, %ownership)
{
%path = "saves/" @ MissionInfo.saveName @ "/" @ %name @ ".bls";
if(!isWriteableFileName(%path))
{
error("Cannot save to file: ", %path);
return;
}
%file = new FileObject();
%file.openForWrite(%path);
%file.writeLine("This is a Blockland save file.  You probably shouldn't modify it cause you'll screw it up.");
%file.writeLine("1"); // What does this mean?
%file.writeLine(%desc);
for(%i=0;%i<64;%i++)
%file.writeLine(getColorIDTable(%i));
%bricks = 0;
for(%i=0;%i<mainBrickGroup.getCount();%i++)
%bricks += mainBrickGroup.getObject(%i).getCount();
%file.writeLine("Linecount " @ %bricks);
for(%d=0;%d<2;%d++)
{
for(%i=0;%i<mainBrickGroup.getCount();%i++)
{
%group = mainBrickGroup.getObject(%i);
for(%a=0;%a<%group.getCount();%a++)
{
%brick = %group.getObject(%a);
if(!(%d ^ %brick.isBasePlate()))
continue;
%print = (%brick.getDataBlock().subCategory $= "Prints") ? getPrintTexture(%brick.getPrintID()) : ""; // Possibly better way to check?
%file.writeLine(%brick.getDataBlock().uiName @ "\" " @ %brick.getPosition() SPC %brick.getAngleID() SPC %brick.isBasePlate() SPC %brick.getColorID() SPC %print SPC %brick.getColorFXID() SPC %brick.getShapeFXID() SPC %brick.isRayCasting() SPC %brick.isColliding() SPC %brick.isRendering());
if(%ownership && %brick.isBasePlate() && !$Server::LAN)
%file.writeLine("+-OWNER " @ getBrickGroupFromObject(%brick).bl_id);
if(%events)
{
if(%brick.getName() !$= "")
%file.writeLine("+-NTOBJECTNAME " @ %brick.getName());
if(%brick.numEvents > 0)
{
for(%b=0;%b<%brick.numEvents;%b++)
{
%targetClass = %brick.eventTargetIdx[%b] >= 0 ? getWord(getField($InputEvent_TargetListfxDTSBrick_[%brick.eventInputIdx[%b]], %brick.eventTargetIdx[%b]), 1) : "fxDtsBrick";
%paramList = $OutputEvent_parameterList[%targetClass, %brick.eventOutputIdx[%b]];
%params = "";
for(%c=0;%c<4;%c++)
{
if(firstWord(getField(%paramList, %c)) $= "dataBlock" && %brick.eventOutputParameter[%b, %c + 1] >= 0)
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1].uiName;
else
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1];
}
%file.writeLine("+-EVENT" TAB %b TAB %brick.eventEnabled[%b] TAB %brick.eventInput[%b] TAB %brick.eventDelay[%b] TAB %brick.eventTarget[%b] TAB %brick.eventNT[%b] TAB %brick.eventOutput[%b] @ %params);
}
}
}
if(isObject(%brick.emitter))
%file.writeLine("+-EMITTER " @ %brick.emitter.emitter.uiName @ "\" " @ %brick.emitterDirection);
if(%brick.getLightID() >= 0)
%file.writeLine("+-LIGHT " @ %brick.getLightID().getDataBlock().uiName @ "\" "); // Not sure if something else comes after the name
if(isObject(%brick.item))
%file.writeLine("+-ITEM " @ %brick.item.getDataBlock().uiName @ "\" " @ %brick.itemPosition SPC %brick.itemDirection SPC %brick.itemRespawnTime);
if(isObject(%brick.audioEmitter))
%file.writeLine("+-AUDIOEMITTER " @ %brick.audioEmitter.getProfileID().uiName @ "\" "); // Not sure if something else comes after the name
if(isObject(%brick.vehicleSpawnMarker))
%file.writeLine("+-VEHICLE " @ %brick.vehicleSpawnMarker.uiName @ "\" " @ %brick.reColorVehicle);
}
}
}
%file.close();
%file.delete();
}

I actually bumped into the dediSave script on RTB. However, I was curious as to what should be put in for %events and %ownership in the function call. I want to assume they are boolean true/false, does anyone know for sure?

Also, would it be possible to call that function via schedule()? I'll probably dive into this problem more seriously tomorrow evening after work, but I want to make sure my ideas are actually workable first.

If you're going to use that, I think you need to replace:
Code: [Select]
if(firstWord(getField(%paramList, %c)) $= "dataBlock" && %brick.eventOutputParameter[%b, %c + 1] >= 0)
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1].uiName;
else
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1];
with:
Code: [Select]
if(firstWord(getField(%paramList, %c)) $= "dataBlock" && isObject(%brick.eventOutputParameter[%b, %c + 1]))
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1].getDataBlock();
else
%params = %params TAB %brick.eventOutputParameter[%b, %c + 1];

Also saving prints will work, but it doesn't save them in the way it should.
« Last Edit: June 24, 2009, 01:15:10 PM by Randy »

And yes, you can run this function through schedule.