Script that iterates over all items on server?
Script that iterates over all items on server?
Hello there,
Is there a possibility to write a script that iterates over all the items that exist on the server? We've had several changes on our shard and I'd love to make some items like weapons and armors all consistent in their configuration and their naming.
So I'd like to run a script once at startup that goes through all the items and sets their properties etc. in the correct way. The problem is: I do not have the slightest idea on how to achieve this :mad:
Can anyone help me?
Is there a possibility to write a script that iterates over all the items that exist on the server? We've had several changes on our shard and I'd love to make some items like weapons and armors all consistent in their configuration and their naming.
So I'd like to run a script once at startup that goes through all the items and sets their properties etc. in the correct way. The problem is: I do not have the slightest idea on how to achieve this :mad:
Can anyone help me?
Hmm. I had a problem when I was converting from skillid to attributes on all my magic items. All the cprops on all magic items was wrong.
My solution wasn't applicable to you, but I decided to patch into the equip scripts and do it from there.
That way the items were all converted at shard startup when the npcs were re-created and equipped and also whenever you manually equipped something or used itemid - so that the player would never know it wasn't being converted until they worked with it.
However, your problem is a bit more complex because you have to name them too. I had a similar problem when we had to rename all our towns and some of the npc races because of a copyright issue. My solution was to not be clever because we didn't have time, but shutdown the shard and edit the savegame files - at least I had tools that could search and replace in files to help me.
My solution wasn't applicable to you, but I decided to patch into the equip scripts and do it from there.
That way the items were all converted at shard startup when the npcs were re-created and equipped and also whenever you manually equipped something or used itemid - so that the player would never know it wasn't being converted until they worked with it.
However, your problem is a bit more complex because you have to name them too. I had a similar problem when we had to rename all our towns and some of the npc races because of a copyright issue. My solution was to not be clever because we didn't have time, but shutdown the shard and edit the savegame files - at least I had tools that could search and replace in files to help me.
Code: Select all
function GetAllObjectsOnShard()
var objects := array;
// First process all top level objects.
foreach realm_name in ( Realms() )
foreach multi in ( ListMultisInBox(0, 0, -128, realm.width, realm.height, 128, realm_name) )
if ( !(multi in objects) )
objects.Append(multi);
endif
endforeach
foreach object in ( ListObjectsInBox(0, 0, -128, realm.width, realm.height, 128, realm_name) )
if ( !(object in objects) )
objects.Append(object);
endif
endforeach
endforeach
// Process all player characters
foreach accout_name in ( ListAccounts() )
var account := FindAccount(account_name);
var i;
for ( i:=1; i<=6; i:=i+1 )
var object := account.GetCharacter(i);
if ( object )
if ( !(object in objects) )
objects.Append(object);
endif
endif
endfor
endforeach
// Process all storage areas
var storage_areas := StorageAreas();
foreach area_name in ( storage_areas )
var storage_area := storage_areas[area_name];
foreach root_container in ( storage_area )
if ( !(root_container in objects) )
objects.Append(root_container);
endif
foreach item in ( EnumerateItemsInContainer(root_container) )
if ( !(item in objects) )
objects.Append(itemt);
endif
endforeach
endforeace
endforeach
return objects;
endfunction
-
Barbeirosa
I wouldn't run any such script while players were online at all due to the memory use and CPU use it would generate. Slapping 'sleeps' in scripts seems to be a way people avoid apparent problems in scripts (for example, to avoid the 'runaway script' warnings), but usually I think people have no clue what they are doing, and they are just masking real problems. It's kind of like fixing that "Check Engine" light in your car by cutting the wires that power it, instead of fixing the problem that caused the light to come on in the first place.
With no players on, I would -NOT- put sleeps in it - in fact, I would run it critical or at maximum priority so that it finishes as quickly as possible, and doesn't sit there taking forever due to all those sleepms(100) calls. I would assume anything important enough to want to fix ALL the items on the shard would also be important enough that you would not want any concurrency issues arising from actions players might take.
I mean... do the math here; 100ms is 1/10 a second. A sleep will give you at least that much time between each item, allowing other scripts to run for at least that long. Meanwhile, you still have this huge array being built up in memory and stored, while you are letting other things happen concurrently. 1/10 of a second between each item delay, and you could easily be causing such a script to run for a day or longer depending on the size of your shard.
Perfect example of fixing the Check Engine light by cutting the wires that power it... and this, from a 'Distro Developer'.
With no players on, I would -NOT- put sleeps in it - in fact, I would run it critical or at maximum priority so that it finishes as quickly as possible, and doesn't sit there taking forever due to all those sleepms(100) calls. I would assume anything important enough to want to fix ALL the items on the shard would also be important enough that you would not want any concurrency issues arising from actions players might take.
I mean... do the math here; 100ms is 1/10 a second. A sleep will give you at least that much time between each item, allowing other scripts to run for at least that long. Meanwhile, you still have this huge array being built up in memory and stored, while you are letting other things happen concurrently. 1/10 of a second between each item delay, and you could easily be causing such a script to run for a day or longer depending on the size of your shard.
Perfect example of fixing the Check Engine light by cutting the wires that power it... and this, from a 'Distro Developer'.
Yeah, it might be some kind of cutting the wires... but first of all I'd like to say THANK YOU for the nice script! It at least shows how it is possible to iterate through alle the items and that is exactly what I was looking for.
I will simply put the operation I want to do to the item inside the loop an won't return anything and... hey, it might run for 2 hours or so, but in the end I will have fixed all the stuff I wanted to and I won't have to make up a perl-script or something else to edit the savegame-files.
So, thanks again for all the answers.
I will simply put the operation I want to do to the item inside the loop an won't return anything and... hey, it might run for 2 hours or so, but in the end I will have fixed all the stuff I wanted to and I won't have to make up a perl-script or something else to edit the savegame-files.
So, thanks again for all the answers.
-
mr bubbles
- Grandmaster Poster
- Posts: 120
- Joined: Thu Jan 18, 2007 2:34 am
-
Barbeirosa
I wasn't saying the script posted was 'cutting the wires'; I was saying that added sleeps in there would have been doing that. I recommend making sure no one can log on to your shard while you run the script, and leaving NO sleeps in it at all - and maybe even running it critical, so that it finishes as quickly as possible.abraxas wrote:Yeah, it might be some kind of cutting the wires... but first of all I'd like to say THANK YOU for the nice script! It at least shows how it is possible to iterate through alle the items and that is exactly what I was looking for.
The script was just made to show you how to do it. I agree that it's best to do your work inside the script written above instead of using the return array. I would just not recommend you try to do this while your shard has players on it, and just let it take over and finish as fast as it can.
I put sleeps in foreach loops even for small arrays, doesn't matter to me if there are people online or how much time it'll take. Why put sleeps in there? Watch the console as it runs through 100,000 items without any sleeps. It's just how I was tought and I'm stickin' too it, 
And Babbles, I do highly suggest to anyone to put sleepms's in there foreach loops to prevent RUNAWAYS. Unless of course you enjoy them(I think barb might be one!).
I just tested SleepMS(2) with 50,000 items and it didn't go runaway. So that could be the bare minimum. I should of tired 1MS... ack =P
And Babbles, I do highly suggest to anyone to put sleepms's in there foreach loops to prevent RUNAWAYS. Unless of course you enjoy them(I think barb might be one!).
I just tested SleepMS(2) with 50,000 items and it didn't go runaway. So that could be the bare minimum. I should of tired 1MS... ack =P
-
Barbeirosa
Yup. Just like I said. Cutting the wires to turn off the Check Engine light, instead of trying to actually understand what's going on.MontuZ wrote:And Babbles, I do highly suggest to anyone to put sleepms's in there foreach loops to prevent RUNAWAYS. Unless of course you enjoy them(I think barb might be one!).
"Runaway scripts" are simply something that POL reports to you on the assumption that it's a bad thing. It's an "Idiot Light" sort of thing... just like that "Check Engine" light. Simply putting sleeps in there does -nothing at all- except avoid that 'Idiot Light' from coming on. That's all you are doing. To suggest otherwise is to prove you are completely ignorant about how threading works in general, and how POL's script scheduling works in particular.
When you sprinkle sleeps everywhere willy-nilly, without any concern for what is actually being done, you are being sure to avoid that idiot light. But, guess what? Your script can still bring your shard to its knees, even with sleeps.
Scripting POL is not like just driving your car to work every day. It's more like being a high-performance car mod freak, playing with the innards of your engine to get the most performance out of it. When you do that, you are going to find that occasionally, your "Check Engine" light is going to turn on. You can bury your head in the sand and just cut the wire, OR you can make an effort to understand what's going on, and why that "Check Engine" light is coming on. Perhaps it's actually not a problem at all.
In the case of the above script, a runaway is no big deal. You want the script to run FAST and be COMPLETED, and you should not be interested in having anything running at the same time. Yes... your "Check Engine" light is going to flash up a storm while that's running - but a scripter who has any clue what they are doing would know why, and would know that it's not a bad thing at all. That actually, in this case, it's a GOOD thing.
But maybe this is why the distro is in such a sorry state... having people like this working on it.
-
Barbeirosa
Exactly, Gnafu!Gnafu wrote:That script is expected to go runaway because is wanted to do lots of things.
So obviously it can freeze the server.
To be sure to avoid errors, run it without pcs online.
It's certainly possible to write something to iterate through, parse, modify and save the altered data in the save files. However, I think it's easier (and safer - you needn't worry about errors in your parsing code) to simply set up POL specially to run with no connections, and simply do all the work and then do a world save and shutdown. Either way, you have to shut down POL and do this work. Doing it within POL itself gives you the benefit of POL's own parsing and saving of its data.Gnafu wrote:I'm thinking if it's possible to iterate through the items directly in the storage file.... :?:
That said, for the times I have decided to write a program that parsed and modified save data, it goes MUCH faster than POL can do it, for some types of things. Probably playing with properties on items isn't a big deal, but one loop I had once done to set/erase properties on all the accounts in the game was actually taking a second or two per account simply to set and/or erase a handful of account properties. I think that's an issue unique to accounts and account properties, however, and does not affect any other POL objects. (perhaps because account changes are persisted to the file immediately?)
I once had the check engine light on in my car for about a month. I hooked up my homegrown OBDII scanner and discovered it was just a faulty O2 sensor. The sucker was siezed onto the intake manifold so I had to take a torch to that mother ... I installed the new one with that anti-sieze grease stuff...
Anyway my car is not a performance car and is a piece of crap ... just thought I could provide a useless analogy ...
Maybe sleeps are like that anti-sieze grease ... or maybe they're like my crappy car ... in any case, forget about riced out cars and get yourself one of these babies!
http://en.wikipedia.org/wiki/Lamborghin ... %C3%A9lago
Anyway my car is not a performance car and is a piece of crap ... just thought I could provide a useless analogy ...
Maybe sleeps are like that anti-sieze grease ... or maybe they're like my crappy car ... in any case, forget about riced out cars and get yourself one of these babies!
http://en.wikipedia.org/wiki/Lamborghin ... %C3%A9lago
-
mr bubbles
- Grandmaster Poster
- Posts: 120
- Joined: Thu Jan 18, 2007 2:34 am
-
Barbeirosa
I think Austin wrote it exactly correctly. It would have been a mistake to have put sleeps in that script. But I guess it's easier to just assume someone else made a mistake, rather than even consider the possibility that you might actually be wrong.tekproxy wrote:SleepMS(2) works fine, as well.
And Austin probably wrote that right off the top of his head. Give him a break