SHOW:
|
|
- or go back to the newest paste.
| 1 | //Author: Kalphiter | |
| 2 | ||
| 3 | //It is not a good idea to copy this script as someone has already packaged it into an add-on and improved it: | |
| 4 | //http://forum.blockland.us/index.php?topic=285601.0 | |
| 5 | ||
| 6 | ||
| 7 | //Derived from autosaver by Destiny/Zack0Wack0: | |
| 8 | //Server_AutoSaver.zip http://orbs.daprogs.com/rtb/forum.returntoblockland.com/dlm/viewFileadd1.html?id=709 | |
| 9 | ||
| 10 | //This autosaver was originally distributed to all servers hosted by Kaphost, but was not intended to be private. | |
| 11 | ||
| 12 | //Modifications from the original: | |
| 13 | ||
| 14 | //This autosaver will not lock up the server; it does not interfere with gameplay and it reports how long it took to | |
| 15 | //save all the bricks. | |
| 16 | ||
| 17 | //This autosaver FULLY PRESERVES ownership, whereas the original uses the space-saving ground-brick-based ownership model | |
| 18 | //also employed by the default brick saving method on the escape menu. | |
| 19 | ||
| 20 | $kaphost::AS::dir = "base/server/kaphost/autosave"; | |
| 21 | ||
| 22 | if(isFile("Add-Ons/System_ReturnToBlockland/server.cs"))
| |
| 23 | {
| |
| 24 | if(!$RTB::RTBR_ServerControl_Hook) | |
| 25 | exec("Add-Ons/System_ReturnToBlockland/RTBR_ServerControl_Hook.cs");
| |
| 26 | ||
| 27 | RTB_registerPref("Interval", "Autosaver", "$kaphost::AS::interval", "int 0 180", "Server_AutoSaver", 5, 0, 0);
| |
| 28 | RTB_registerPref("Announce", "Autosaver", "$kaphost::AS::announce", "bool", "Server_AutoSaver", 1, 0, 0);
| |
| 29 | } | |
| 30 | else | |
| 31 | {
| |
| 32 | $kaphost::AS::announce = false; | |
| 33 | $kaphost::AS::interval = 5; | |
| 34 | } | |
| 35 | ||
| 36 | function kaphost_AS1_begin() | |
| 37 | {
| |
| 38 | deleteVariables("$kaphost::AS_groups::group*");
| |
| 39 | ||
| 40 | cancel($kaphost_AS_schedule); | |
| 41 | ||
| 42 | if($kaphost::AS::announce) | |
| 43 | messageAll('', "\c5Autosaving...");
| |
| 44 | ||
| 45 | $time_beg = getSimTime(); | |
| 46 | ||
| 47 | %dir = $kaphost::AS::dir; | |
| 48 | $kaphost::AS_groups::group_count = 0; | |
| 49 | $kaphost::AS_groups::cur_group = 0; | |
| 50 | $kaphost::AS_groups::brick_count = 0; | |
| 51 | ||
| 52 | for(%i = 0; %i < mainBrickGroup.getCount(); %i++) | |
| 53 | {
| |
| 54 | %g = mainBrickGroup.getObject(%i); | |
| 55 | %b = %g.getCount(); | |
| 56 | if(%b > 0) | |
| 57 | {
| |
| 58 | %g.kaphost_AS_stop = %b; | |
| 59 | $kaphost::AS_groups::group[$kaphost::AS_groups::group_count] = %g; | |
| 60 | $kaphost::AS_groups::group_count++; | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | $kaphost::AS::FO = %f = new FileObject(); | |
| 65 | %f.openForWrite(%dir @"/TEMP1.bls"); | |
| 66 | ||
| 67 | if(isObject($kaphost::AS_groups::group[0])) | |
| 68 | kaphost_AS1_nextGroup(%f); | |
| 69 | } | |
| 70 | ||
| 71 | function kaphost_AS1_nextGroup(%f) | |
| 72 | {
| |
| 73 | if($kaphost::AS_groups::cur_group == $kaphost::AS_groups::group_count) | |
| 74 | return kaphost_AS1_end(%f); | |
| 75 | ||
| 76 | %g = $kaphost::AS_groups::group[$kaphost::AS_groups::cur_group]; | |
| 77 | $kaphost::AS_groups::cur_group++; | |
| 78 | kaphost_AS1_nextBrick(%f, %g, 0); | |
| 79 | } | |
| 80 | ||
| 81 | function kaphost_AS1_nextBrick(%f, %g, %c) | |
| 82 | {
| |
| 83 | if(%c >= %g.getCount()) | |
| 84 | return kaphost_AS1_nextGroup(%f); | |
| 85 | ||
| 86 | %f.writeLine(%g.getObject(%c).getID()); | |
| 87 | ||
| 88 | $kaphost::AS_groups::brick_count += 1; | |
| 89 | ||
| 90 | schedule(0, 0, kaphost_AS1_nextBrick, %f, %g, %c+1); | |
| 91 | } | |
| 92 | ||
| 93 | function kaphost_AS1_end(%f) | |
| 94 | {
| |
| 95 | %f.close(); | |
| 96 | %f.delete(); | |
| 97 | ||
| 98 | //Phase 1 complete | |
| 99 | kaphost_AS2_begin(); | |
| 100 | } | |
| 101 | ||
| 102 | function kaphost_AS2_begin() | |
| 103 | {
| |
| 104 | %events = 1; | |
| 105 | %ownership = 1; | |
| 106 | ||
| 107 | %dir = $kaphost::AS::dir; | |
| 108 | ||
| 109 | %f_A = new FileObject(); | |
| 110 | %f_B = new FileObject(); | |
| 111 | %f_A.path = %dir @"/TEMP1.bls"; | |
| 112 | %f_B.path = %dir @"/TEMP2.bls"; | |
| 113 | ||
| 114 | %f_B.openForWrite(%f_B.path); | |
| 115 | %f_B.writeLine("This is a Blockland save file. You probably shouldn't modify it cause you'll screw it up.");
| |
| 116 | %f_B.writeLine("1");
| |
| 117 | %f_B.writeLine(%desc); | |
| 118 | ||
| 119 | for(%i = 0; %i < 64; %i++) | |
| 120 | %f_B.writeLine(getColorIDTable(%i)); | |
| 121 | ||
| 122 | %f_B.writeLine("Linecount "@ $kaphost::AS_groups::brick_count);
| |
| 123 | ||
| 124 | $kaphost::AS_groups::brick_count = 0; | |
| 125 | ||
| 126 | %f_A.openForRead(%f_A.path); | |
| 127 | kaphost_AS2_nextLine(%f_A, %f_B); | |
| 128 | } | |
| 129 | ||
| 130 | function kaphost_AS2_nextLine(%f_A, %f_B, %c) | |
| 131 | {
| |
| 132 | %c++; | |
| 133 | ||
| 134 | if(!%f_A.isEOF()) | |
| 135 | {
| |
| 136 | %brick = %f_A.readLine(); | |
| 137 | if(isObject(%brick)) | |
| 138 | {
| |
| 139 | $kaphost::AS_groups::brick_count++; | |
| 140 | if(%brick.getDataBlock().hasPrint) | |
| 141 | {
| |
| 142 | %texture = getPrintTexture(%brick.getPrintId()); | |
| 143 | %path = filePath(%texture); | |
| 144 | %underscorePos = strPos(%path, "_"); | |
| 145 | %name = getSubStr(%path, %underscorePos + 1, strPos(%path, "_", 14) - 14) @ "/" @ fileBase(%texture); | |
| 146 | if($printNameTable[%name] !$= "") | |
| 147 | %print = %name; | |
| 148 | } | |
| 149 | ||
| 150 | %f_B.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()); | |
| 151 | ||
| 152 | if((%ownership = 1) && !$Server::LAN) | |
| 153 | %f_B.writeLine("+-OWNER " @ getBrickGroupFromObject(%brick).bl_id);
| |
| 154 | ||
| 155 | if(%events = 1) | |
| 156 | {
| |
| 157 | if(%brick.getName() !$= "") | |
| 158 | %f_B.writeLine("+-NTOBJECTNAME " @ %brick.getName());
| |
| 159 | ||
| 160 | for(%b = 0; %b < %brick.numEvents; %b++) | |
| 161 | {
| |
| 162 | %targetClass = %brick.eventTargetIdx[%b] >= 0 ? getWord(getField($InputEvent_TargetListfxDTSBrick_[%brick.eventInputIdx[%b]], %brick.eventTargetIdx[%b]), 1) : "fxDtsBrick"; | |
| 163 | %paramList = $OutputEvent_parameterList[%targetClass, %brick.eventOutputIdx[%b]]; | |
| 164 | %params = ""; | |
| 165 | for(%c = 0; %c < 4; %c++) | |
| 166 | {
| |
| 167 | if(firstWord(getField(%paramList, %c)) $= "dataBlock" && isObject(%brick.eventOutputParameter[%b, %c + 1])) | |
| 168 | %params = %params TAB %brick.eventOutputParameter[%b, %c + 1]; | |
| 169 | else | |
| 170 | %params = %params TAB %brick.eventOutputParameter[%b, %c + 1]; | |
| 171 | } | |
| 172 | %f_B.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);
| |
| 173 | } | |
| 174 | } | |
| 175 | if(isObject(%brick.emitter)) | |
| 176 | %f_B.writeLine("+-EMITTER " @ %brick.emitter.emitter.uiName @ "\" " @ %brick.emitterDirection);
| |
| 177 | ||
| 178 | if(%brick.getLightID() >= 0) | |
| 179 | %f_B.writeLine("+-LIGHT " @ %brick.getLightID().getDataBlock().uiName @ "\" "); // Not sure if something else comes after the name
| |
| 180 | ||
| 181 | if(isObject(%brick.item)) | |
| 182 | %f_B.writeLine("+-ITEM " @ %brick.item.getDataBlock().uiName @ "\" " @ %brick.itemPosition SPC %brick.itemDirection SPC %brick.itemRespawnTime);
| |
| 183 | ||
| 184 | if(isObject(%brick.audioEmitter)) | |
| 185 | %f_B.writeLine("+-AUDIOEMITTER " @ %brick.audioEmitter.getProfileID().uiName @ "\" "); // Not sure if something else comes after the name
| |
| 186 | ||
| 187 | if(isObject(%brick.vehicleSpawnMarker)) | |
| 188 | %f_B.writeLine("+-VEHICLE " @ %brick.vehicleSpawnMarker.uiName @ "\" " @ %brick.reColorVehicle);
| |
| 189 | } | |
| 190 | ||
| 191 | return schedule(0, 0, kaphost_AS2_nextLine, %f_A, %f_B, %c); | |
| 192 | } | |
| 193 | ||
| 194 | else | |
| 195 | {
| |
| 196 | kaphost_AS2_end(%f_A, %f_B); | |
| 197 | } | |
| 198 | } | |
| 199 | ||
| 200 | function kaphost_AS2_end(%f_A, %f_B) | |
| 201 | {
| |
| 202 | %f_A.close(); | |
| 203 | %f_B.close(); | |
| 204 | %dir = $kaphost::AS::dir; | |
| 205 | ||
| 206 | for(%a = 5; %a >= 0; %a--) | |
| 207 | if(isFile(%dir @"/auto"@ %a @".bls")) | |
| 208 | {
| |
| 209 | if(%a == 5) | |
| 210 | fileDelete(%dir @"/auto"@ %a @".bls"); | |
| 211 | ||
| 212 | else | |
| 213 | fileCopy(%dir @"/auto"@ %a @".bls", %dir @"/auto"@ (%a+1) @".bls"); | |
| 214 | } | |
| 215 | ||
| 216 | fileCopy(%f_B.path, %dir @"/auto0.bls"); | |
| 217 | fileDelete(%f_A.path); | |
| 218 | fileDelete(%f_B.path); | |
| 219 | ||
| 220 | %f_A.delete(); | |
| 221 | %f_B.delete(); | |
| 222 | ||
| 223 | if($kaphost::AS::interval < 5) | |
| 224 | $kaphost::AS::interval = 1; | |
| 225 | ||
| 226 | if($kaphost::AS::interval > 180) | |
| 227 | $kaphost::AS::interval = 180; | |
| 228 | ||
| 229 | %diff = (getSimTime() - $time_beg); | |
| 230 | ||
| 231 | if($kaphost::AS::announce) | |
| 232 | messageAll('', "\c5Autosaved \c6"@ $kaphost::AS_groups::brick_count @" \c5bricks in \c6"@ (%diff/1000) @" \c5seconds.");
| |
| 233 | ||
| 234 | %next_time = 60 * 1000 - %diff; | |
| 235 | %next_time = $kaphost::AS::interval * 60 * 1000 - %diff; | |
| 236 | if(%next_time < 60000) | |
| 237 | %next_time = $kaphost::AS::interval * 60 * 1000; | |
| 238 | ||
| 239 | $kaphost_AS_schedule = schedule(%next_time, 0, kaphost_AS1_begin); | |
| 240 | } | |
| 241 | ||
| 242 | $kaphost_AS_schedule = schedule(60 * 7.5 * 1000, 0, kaphost_AS1_begin); |