Implementing: Instancing

EQ2Emulator Development forum.

Moderator: Team Members

User avatar
thefoof
Retired
Posts: 630
Joined: Wed Nov 07, 2012 7:36 pm
Location: Florida

Re: Implementing: Instancing

Post by thefoof » Sat Sep 14, 2013 2:16 pm

Jabantiz wrote:
thefoof wrote:Also if this is going to be a huge emu wide overhaul let me know what needs to be done and I'll help convert some of the .cpp's over.
Thanks for the offer, it should be mostly in the zoneserver.cpp, spawn.cpp, entity.cpp, npc.cpp, player.cpp, and npc_ai.cpp, also it is not a simple conversion some code has to be rewritten to work with the new map. I think I have converted everything but a few lists in zoneserver already though, going faster then I expected.

I am still waiting for johns input, but almost have it all converted locally, I also haven't noticed the server crashes from zoning from cave of illboding to frostfang using the door, no random invalid spawn crash, and while I may have just been lucky I haven't had the ping time out when logging in. Also found a crash bug related to spells as a result of my testing, combat bug that prevented the player from auto attacking, and may have fixed the /reload spawnscripts that caused the zone server to crap out.
Talk about a hotfix LOL

Jabantiz
Lead Developer
Posts: 2912
Joined: Wed Jul 25, 2007 2:52 pm
Location: California

Re: Implementing: Instancing

Post by Jabantiz » Sun Sep 15, 2013 12:59 pm

Finished the changes last night and have been doing all tests I can think of and no crashes or bugs from the changes, went ahead and committed the code to Dev SVN as it looks to solve a lot if not all the invalid pointer crashes we have been having.

Basically this converts lists or variables that maintain a spawn pointer for future use to an int32 of the spawn id (spawn->GetID()), when you need to use the pointer you would call GetSpawnByID() from the zone server, you can then check the pointer that returns and if it is valid do your code, if it is not valid you can remove the value from the list or set the variable to 0 thereby clearing the invalid pointer and allowing the server to continue on.

Here is an example

Code: Select all

Spawn* Spawn::GetTarget() {
    // target was a Spawn* pointer, it is now an int32, this function use to be "return target;"
    // if by some chance the spawn pointed to an object deleted in the zone server this function
    // could return an invalid pointer that could cause a crash if used some where else

    // Lets get a spawn pointer for the id we have
    Spawn* ret = GetZone()->GetSpawnByID(target);

    // Lets check to see if the id still points to a valid spawn
    if (!ret) {
        // The spawn the id points to is no longer valid, lets clear the id
        target = 0;
    }

    // Return the spawn pointer we have
    return ret;
}
This is a simple example, I added the comments only here in this post to explain what is going on. As you can see this allows us to catch invalid spawns and handle them.


I will attempt to explain why this works for those interested.
In the zone server all active spawns are maintained in the spawn_list, when the zone server deletes a spawn it moves it out of the spawn list and into another list to maintain the pointer for 30 secs, allowing other pointers to the object to continue to work, after the time is up it is finally deleted with a safe_delete(). The problem is we would grab a pointer from the spawn_list and hold on to it in another list, sometimes for a long period of time and when we finally used it the object it pointed to has already been deleted causing it to be an invalid pointer and cause a server crash.

The new way has all the lists using the spawn id, when you go to use the spawn you have to call the GetSpawnByID() function to get the spawn pointer from the spawn_list, if the spawn has already been moved out of the spawn_list it returns 0 allowing you to handle it and no possibility of crashes due to an invalid pointer.


If any issues pop up let me know, from what I have tested it seems to have made the server a lot more stable, but lets face it I suck testing my own code.

User avatar
thefoof
Retired
Posts: 630
Joined: Wed Nov 07, 2012 7:36 pm
Location: Florida

Re: Implementing: Instancing

Post by thefoof » Sun Sep 15, 2013 3:27 pm

Thanks for the update on that Jab, I'll work on some content tonight and see if there's any weird behavior at all.

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Implementing: Instancing

Post by John Adams » Sun Sep 15, 2013 4:11 pm

Jabantiz wrote:I am still waiting for johns input
Aside from my whining about world crashes, I probably have little input on what you want to change. I am confident in your abilities, as the Combat stuff was a success - plus other non-MutexMap code you've written seems to still work fine under multi-player. For a hobbyist, you seem to do quite well :)

You know I hate the Mutex* stuff, mostly because I don't understand it and hate any code that "eats" the true error so we cannot debug easily. Anything you want to do to remedy that, you have my blessing.

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Implementing: Instancing

Post by Ememjr » Mon Aug 14, 2017 6:53 am

does anyone a a reference to the table this refers to from worlddatabase.cpp

Code: Select all

SELECT spawn_location_entry_id, respawn_time FROM instance_spawns_removed WHERE instance_id = %i AND spawn_type = %i"
apparently its used in instancing and used when you buy a house, so would like to get the table in my db

Jabantiz
Lead Developer
Posts: 2912
Joined: Wed Jul 25, 2007 2:52 pm
Location: California

Re: Implementing: Instancing

Post by Jabantiz » Mon Aug 14, 2017 3:48 pm

Odd that you didn't get that with the DB patcher, here is the table though

Code: Select all

CREATE TABLE `instance_spawns_removed` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`instance_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
	`spawn_type` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
	`spawn_location_entry_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
	`respawn_time` INT(10) UNSIGNED NOT NULL DEFAULT '0',
	PRIMARY KEY (`id`),
	INDEX `InstanceIDX` (`instance_id`),
	INDEX `SpawnIDX` (`spawn_location_entry_id`),
	CONSTRAINT `FK_instance_spawns` FOREIGN KEY (`spawn_location_entry_id`) REFERENCES `spawn_location_entry` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
	CONSTRAINT `FK_instance_zones` FOREIGN KEY (`instance_id`) REFERENCES `instances` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Implementing: Instancing

Post by Ememjr » Tue Sep 26, 2017 8:12 am

is there a way to add a spawn to a specific instance of a zone while the instance is active, this is for housing, i tried to create a spawn of an object in a house, a table, by using the spawn create, then spawn add, it added it to the base zone so it appears in ever house of tha type. i need to be able to add an object (spawn) to an instance zone when the zone is loading based on the character house items, or an import of a housing template.

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Implementing: Instancing

Post by Ememjr » Tue Sep 26, 2017 8:13 am

also is there a way to determine the instance id of the zone you are currently in

User avatar
Ememjr
Team Member
Posts: 975
Joined: Wed Mar 15, 2017 9:41 am
EQ2Emu Server: Perseverance

Re: Implementing: Instancing

Post by Ememjr » Tue Sep 26, 2017 2:04 pm

well damn got it figured out, it was right in front of me the whole time.
when you use /create spawn it places it in your zone and when another person comes into that same instance they will see the created spawn
the key is not to use spawn create on it. now ill just make the list of what gets create when a house instance is loaded

User avatar
Zcoretri
Team Member
Posts: 1642
Joined: Fri Jul 27, 2007 12:55 pm
Location: SoCal

Re: Implementing: Instancing

Post by Zcoretri » Tue Sep 26, 2017 7:30 pm

Sometimes the hardest thing to see is what is right in front of you. Glad you figured it out. :mrgreen:

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Implementing: Instancing

Post by John Adams » Fri Jul 20, 2018 5:53 pm

I have attempted to read through this whole topic before asking (ow, my eye) but I need a reminder... [mention]Jabantiz[/mention] in the Zones table, for an Instance'able zone, the fields for `default_reenter_time`, `default_reset_time` and `default_lockout_time` are all in "seconds", correct?

Code like this makes me think so:

Code: Select all

if (Timer::GetUnixTimeStamp() < data->last_success_timestamp + data->success_lockout_time) {

Jabantiz
Lead Developer
Posts: 2912
Joined: Wed Jul 25, 2007 2:52 pm
Location: California

Re: Implementing: Instancing

Post by Jabantiz » Fri Jul 20, 2018 6:05 pm

Yes it should all be in seconds.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest