Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > Code Gallery
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 01-18-2014, 08:17 PM
100Zero100 100Zero100 is offline
Registered User
Join Date: Jul 2006
Posts: 31
100Zero100 is on a distinguished road
Dump Useless Local NPCs

I made this script in 2011-2012 and it worked a bit differently (some stuff was changed it seems). Basically the idea is to delete any putnpc2's that exist on the server, in levels that no longer exist.

The first time running the script on UN (2011-2012) reduced their local NPCs from ~4950 to ~690. Running it on UN earlier today reduced their local NPCs from ~6k to ~4k. Running it on Era about an hour ago reduced their local NPCs from > 10k (loadFolder only goes up to 10k entries) to ~3k after 2 presses (first press: ~6k. second press: ~3k). I've had good experiences with it reducing NPC server startup times as well as NC load times (for servers with slow NCs).

It's part of a bigger NPC. I just snipped this part since it seems the most universal.

PHP Code:
// NaS
const tempFolder "temp/";
const 
npcFolder "npcs/";
const 
prefix "npclocalnpc";
const 
ext ".nw";

function 
onCreated() {
 
purgeLocal();
}
function 
purgeLocal() {
 
temp.folder.loadFolder(npcFolder prefix "*",0);
 
temp.oldSize folder.size();
 for (
temp.fileNamefolder) {
  
temp.file removeEscapesFromFileName(fileName);
  
temp.tokens file.tokenize("_");
  
temp.endlen tokens[tokens.size() - 1].length() + tokens[tokens.size() - 2].length() + 3;
  
temp.lvl file.substring(prefix.length() + 1file.length() - prefix.length() - endlen) @ ext;
  if (!
levelExists(lvl)) {
   
moveFile(npcFolder fileNametempFolder fileName);
   
deleteFile(tempFolder fileName);
  }
 }
 
temp.folder.loadFolder(npcFolder prefix "*",0);
 
temp.newSize folder.size();
 echo(
format("Local NPC count went from %i to %i."oldSizenewSize));

Your NPC server needs rw to the npcs/npclocalnpc* and it also needs rw to some temporary folder (I put temp/, but it can be anything else; defined in const tempFolder). Likely needs 'r' to all of your levels in order for the levelExists() check to run. You can remove the rw when you're done.

Basically, since sometime in 2012 you can no longer deleteFile() anything in npcs/ (even with npc server rw and protectdbnpcs=false in server ops (I tested, jic)), but you can still moveFile() them to another folder and delete them there. It's an unfortunate nuisance, but so it is.

It outputs how many local NPCs were deleted in an echo(), so let me know if your results are interesting.
__________________
Hi. I'm NaS!
Reply With Quote
  #2  
Old 01-18-2014, 08:52 PM
BlueMelon BlueMelon is offline
asdfg
BlueMelon's Avatar
Join Date: Sep 2008
Posts: 1,481
BlueMelon is a splendid one to beholdBlueMelon is a splendid one to beholdBlueMelon is a splendid one to beholdBlueMelon is a splendid one to behold
vouch

best thing under atrius
__________________
http://i.imgur.com/OOJbW.jpg
Reply With Quote
  #3  
Old 01-19-2014, 09:10 AM
xAndrewx xAndrewx is offline
Registered User
xAndrewx's Avatar
Join Date: Sep 2004
Posts: 5,260
xAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud of
Hey Nas <3

Pretty cool- I suppose it only helps on server load up.

A plan for the future is to delete the levels if they are not being used and re-create the level when needed and keep the putnpcs (for houses / gang houses etc)
__________________
Reply With Quote
  #4  
Old 01-19-2014, 02:16 PM
100Zero100 100Zero100 is offline
Registered User
Join Date: Jul 2006
Posts: 31
100Zero100 is on a distinguished road
Quote:
Originally Posted by xAndrewx View Post
Hey Nas <3

Pretty cool- I suppose it only helps on server load up.

A plan for the future is to delete the levels if they are not being used and re-create the level when needed and keep the putnpcs (for houses / gang houses etc)
Levels are not loaded into server memory by default. They are simply in the server's HDD and load when a player enters (and they unload from memory like 5-10 minutes later), same as all level NPCs inside of them. In addition, all this.savelocally putnpc2's function the same.

This script addresses only the putnpc2's that aren't this.savelocally that exist inside of levels that are now deleted. You could expand the script (simply make it recursive) to check the this.savelocally ones, but I saw no need (as they are not in the server's memory anyway). I suppose that could help with file browser opening speed, though (or you can just not give yourself rw to that part of the file browser in the first place! ie "-rw npcs/*/*").

The putnpc2's that don't save locally load up when the NPC server is loaded and are loaded into your NC when you load into the server, so they do create lag in NC loadtimes and NPC server restarting. Additionally, I suspect that a lot of the putnpc2's that exist in defunct levels could likely be the result of corrupt ex-staff who added them to do possibly malicious things (Delete levels, add gralats, whatever).

As an aside, if you wanted to get "serious" with putnpc removal, you may couple this script with another script (or slightly modify it) to detect which levels have the most NPCs, via the same methodology.

Here is a (hack-ish) quick version I made with the script I posted above:

PHP Code:
// NaS
const npcFolder "npcs/";
const 
prefix "npclocalnpc";
const 
ext ".nw";
const 
tempFolder "";

function 
onCreated() {
 
temp.folder.loadfolder("npcs/npclocalnpc*"0);
 echo(
"local npcs:" SPC folder.size());
 
npcInfo();
}
function 
npcInfo() {
 
temp.folder.loadFolder(npcFolder prefix "*",0);
 for (
temp.fileName:folder) {
  
temp.file removeescapesfromfilename(fileName);
  
temp.tokens file.tokenize("_");
  
temp.endlen tokens[tokens.size() - 1].length() + tokens[tokens.size() - 2].length() + 3;
  
temp.lvl file.substring(prefix.length() + 1file.length() - prefix.length() - endlen) @ ext;
  
  if (!(
lvl in temp.lvls)) {
   
temp.lvls.add(lvl);
  }
  
temp.(@lvl)++;
 }
 
temp.amount 0;
 
temp.biggest "";
 for (
temp.lvllvls) {
  if (
temp.(@lvl) > amount) {
   
amount temp.(@lvl);
   
biggest lvl;
  }
 }
 echo(
format("most putnpcs in %s with %i"biggestamount));

Like I said, it's a "hack-ish" fix I threw together (not going for efficiency on this one, just functionality). You run it and it simply echos which level has the most putnpc's.

When I ran it on UN (we had 4k putnpc2's left yesterday when I ran the first script), it got 1.1k hits in 1 level from an old quest. We dumped that level and ran it again and got about 800 NPCs from a spar tourney viewer (the tourney viewers weren't destroying on the serverside properly). We fixed the glitch and dumped that level. We did that for about 5 things.

Then we saw the bulk of the putnpc's left (I checked npcs/ myself for them, which was now loadable!) were of the classes: gralats, gralats_death, newhatdrop, and epdrop.

Those are items players can drop and give to other players. So I simply added an onInitialized() destroy(); clause on them, and rebooted the NPC server; let's be real, that kind of stuff shouldn't be expected to persist a server restart anyway. In the rare event that we reboot the npc server while a player was dropping a hat, we have logging for that anyway.

The remaining NPCs were from the playerhouse system, so we added this.savelocally to those NPCs. All-in-all, we only had about 60 putnpc's left after all of that. I went through them all personally (took about 10-15 min) and they were old BS classes that just forgot to destroy (or just had no script in them), so I just deleted them manually.

In total, the whole project took about 1-1.5 hours, but lowered UN's putnpc2 count from ~6k to 0. But I figure if you just want a quick-fix to remove a bunch of putnpc2's that nobody is using anymore, that script up top is a one-press solution to at least a few thousand!
__________________
Hi. I'm NaS!
Reply With Quote
  #5  
Old 01-20-2014, 10:16 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
Did something like this on the Testbed server back in 2009. This was due the to the fact scripters loved to upload staff tools and write their name with thousands of staff blocks. Best part? putnpcs with non-existing classes

PHP Code:
/*
    Used to clear classes from levels.
    
    By classes I mean staffsigns, staffblocks etc.
    
    just edit 'temp.class' to what class to search for..
    Also remove the 'return;' to enable
      (Comment it out for fast toggling)
    
    -Chompy
*/

/*
  2.feb.09
  
  Most used classes:
  
  1. shared_blocks: 552 times
  
  -- After cleaning --
  
  Found 546x (shared_blocks) in new1.nw
  
  ------------------------------ 1th may
  
  Found 186x (shared_blocks) in firstscript1.nw
  Found 2x (shared_blocks) in jail_outside.nw
  Found 520x (shared_blocks) in era_sewerph-house14-1.nw
  Found 1x (shared_blocks) in ce_shop1.nw
  Found 1x (shared_blocks) in ******.nw
  Found 1x (shared_blocks) in ******.nw

*/

function onCreated() {
  
temp.paths findfiles("*.nw"1);
  
temp.class = "shared_blocks";
  
  return;
  
  for(
temp.path paths) {
    
temp.pos path.tokenize("/");
    
temp.lvl pos[pos.size()-1];
    
temp.lvl2 findlevel(lvl);
    
temp.blocks 0;
    for(
temp.lvl2.npcs) {
      if (class 
in n.joinedclasses) {
        
blocks ++;
        
n.destroy();
      }
    }
    if (
blocks 0) {
      echo(
"Found "blocks @"x ("@class@") in "lvl2.name);
    }
  }

Simply you would do /stats in RC chat, then look for the classes that occured to the most, and put that class name in the script, and it would look through levels for that class and destroy it.

Very old script, never optimized it or anything, but it takes a little different approach than yours.

I think you only need r to the folders the levels are in if I'm not mistaken, can't remember. Found this in an old testbed server backup

NB! Yes, you have no idea how often I saw era weapons, levels and whatever era stuff on the testbed stuff. was so fun deleting it. Most popular server's stuff to mess around in 2009 on testbed.
__________________
Reply With Quote
  #6  
Old 03-11-2014, 02:35 AM
Torankusu Torankusu is offline
Elite Member
Torankusu's Avatar
Join Date: Jun 2001
Posts: 10,065
Torankusu has a spectacular aura aboutTorankusu has a spectacular aura about
Quote:
Originally Posted by 100Zero100 View Post
(loadFolder only goes up to 10k entries)
I am using loadfolder for a different application, but am running into this issue.

I cannot decrease my amount and re-run the script, however.

Do you have any recommendations for checking entries > 10,000 ?
__________________
Quote:
Originally posted by Spark910
Think befreo you type.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 01:12 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.