Script that iterates over all items on server?

Here you can post threads requesting help on the official POL Ultima Online Emulator Core 096.
Note: Core 096 is no longer officially supported.
abraxas
New User
Posts: 5
Joined: Sun Jan 21, 2007 3:35 pm

Script that iterates over all items on server?

Post by abraxas »

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?
Gnafu
Grandmaster Poster
Posts: 136
Joined: Thu Feb 02, 2006 7:29 am

Post by Gnafu »

It will be usefull to me too.

Usually i use Listobjectinbox(0,0, maxX, maxY, realm) and enumerateonlinecharacters() functions.
Is there something to iterate throgh all items in a direct way?
User avatar
OldnGrey
POL Expert
Posts: 657
Joined: Sat Feb 04, 2006 6:26 pm

Post by OldnGrey »

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.
User avatar
Austin
Former Developer
Posts: 621
Joined: Wed Jan 25, 2006 2:30 am

Post by Austin »

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

Yukiko
Distro Developer
Posts: 2826
Joined: Thu Feb 02, 2006 1:41 pm

Post by Yukiko »

Neat idea OldNGrey.
I'll have to use that if I run into weaps with skill numbers rather that attribute names.
User avatar
OldnGrey
POL Expert
Posts: 657
Joined: Sat Feb 04, 2006 6:26 pm

Post by OldnGrey »

Austin - that's gonna be some huge array returned!
User avatar
MontuZ
Forum Regular
Posts: 338
Joined: Fri Feb 10, 2006 8:08 am

Post by MontuZ »

MIGHT WANT TO ADD SOME

SleepMS(100);

In the foreach loops. So your server doesn't go on the fritz.

Come on Austin, that's a newb mistake! =D
Yukiko
Distro Developer
Posts: 2826
Joined: Thu Feb 02, 2006 1:41 pm

Post by Yukiko »

He must have been sober when he wrote it.
*grins*
Barbeirosa

Post by 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'.
abraxas
New User
Posts: 5
Joined: Sun Jan 21, 2007 3:35 pm

Post by abraxas »

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.
mr bubbles
Grandmaster Poster
Posts: 120
Joined: Thu Jan 18, 2007 2:34 am

Post by mr bubbles »

I feel the same way as barb on the sleeps on scripts like this, now im curious as to why you think they should be added :?
Barbeirosa

Post by Barbeirosa »

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.
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.

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.
User avatar
MontuZ
Forum Regular
Posts: 338
Joined: Fri Feb 10, 2006 8:08 am

Post by MontuZ »

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, :D

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

Post by Barbeirosa »

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!).
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.

"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.
Matrix
Neophyte Poster
Posts: 32
Joined: Fri Feb 03, 2006 9:13 am

Post by Matrix »

:o
User avatar
MontuZ
Forum Regular
Posts: 338
Joined: Fri Feb 10, 2006 8:08 am

Post by MontuZ »

Okay, Barb. 8)
Yukiko
Distro Developer
Posts: 2826
Joined: Thu Feb 02, 2006 1:41 pm

Post by Yukiko »

I never ignore the "Check Engine Light" in my car. Everytime that light comes on I always pull over and look under the hood. So far my engine has always been there.
Gnafu
Grandmaster Poster
Posts: 136
Joined: Thu Feb 02, 2006 7:29 am

Post by Gnafu »

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.

I'm thinking if it's possible to iterate through the items directly in the storage file.... :?:
Barbeirosa

Post by Barbeirosa »

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.
Exactly, Gnafu!
Gnafu wrote:I'm thinking if it's possible to iterate through the items directly in the storage file.... :?:
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.

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?)
User avatar
Datus
Apprentice Poster
Posts: 58
Joined: Tue Sep 19, 2006 6:27 am

Post by Datus »

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
mr bubbles
Grandmaster Poster
Posts: 120
Joined: Thu Jan 18, 2007 2:34 am

Post by mr bubbles »

That reminds me i gotta book my car in too. The check engine light has been on for about 3 months now :P Havn't had the time and it is more than likely just faulty wiring like urs... I hope anyway :)
Yukiko
Distro Developer
Posts: 2826
Joined: Thu Feb 02, 2006 1:41 pm

Post by Yukiko »

Mr Bubbles, try inserting some sleep function calls in there. That should make that check engine light go out.
User avatar
tekproxy
Forum Regular
Posts: 352
Joined: Thu Apr 06, 2006 5:11 pm

Post by tekproxy »

SleepMS(2) works fine, as well.

And Austin probably wrote that right off the top of his head. Give him a break :-D
User avatar
MontuZ
Forum Regular
Posts: 338
Joined: Fri Feb 10, 2006 8:08 am

Post by MontuZ »

tekproxy wrote:SleepMS(2) works fine, as well.

And Austin probably wrote that right off the top of his head. Give him a break :-D
Hehe. Yeah, I was just messing with him. He also had about a thousand spelling errors too that I didn't point out. Probably sober when he did it...
Barbeirosa

Post by Barbeirosa »

tekproxy wrote:SleepMS(2) works fine, as well.

And Austin probably wrote that right off the top of his head. Give him a break :-D
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.
Post Reply