Talk about a hotfix LOLJabantiz wrote: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.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.
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.
Implementing: Instancing
Moderator: Team Members
- thefoof
- Retired
- Posts: 630
- Joined: Wed Nov 07, 2012 7:36 pm
- Location: Florida
Re: Implementing: Instancing
-
Jabantiz
- Lead Developer
- Posts: 2912
- Joined: Wed Jul 25, 2007 2:52 pm
- Location: California
Re: Implementing: Instancing
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
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.
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;
}
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.
- thefoof
- Retired
- Posts: 630
- Joined: Wed Nov 07, 2012 7:36 pm
- Location: Florida
Re: Implementing: Instancing
Thanks for the update on that Jab, I'll work on some content tonight and see if there's any weird behavior at all.
- 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
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 wellJabantiz wrote:I am still waiting for johns input
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.
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Implementing: Instancing
does anyone a a reference to the table this refers to from worlddatabase.cpp
apparently its used in instancing and used when you buy a house, so would like to get the table in my db
Code: Select all
SELECT spawn_location_entry_id, respawn_time FROM instance_spawns_removed WHERE instance_id = %i AND spawn_type = %i"-
Jabantiz
- Lead Developer
- Posts: 2912
- Joined: Wed Jul 25, 2007 2:52 pm
- Location: California
Re: Implementing: Instancing
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
;
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Implementing: Instancing
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.
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Implementing: Instancing
also is there a way to determine the instance id of the zone you are currently in
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Implementing: Instancing
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
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
- Zcoretri
- Team Member
- Posts: 1642
- Joined: Fri Jul 27, 2007 12:55 pm
- Location: SoCal
Re: Implementing: Instancing
Sometimes the hardest thing to see is what is right in front of you. Glad you figured it out. 
- 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
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 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
Yes it should all be in seconds.
Who is online
Users browsing this forum: No registered users and 1 guest