EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   Rampage AA (https://www.eqemulator.org/forums/showthread.php?t=26859)

KingMort 11-28-2008 10:18 AM

Rampage AA
 
OK well maybe some servers have not experienced this, and maybe this has already been posted hopefully not anyway..

Rampage AA you can actually crash zones using it.. If you want to block a certain guild it comes in handy you simply pull the entire zone and use it and blam crashage of the zoneage...


The same also applies for Wizard AOE nukes when killing too many mobs at once...

King

AndMetal 11-29-2008 05:51 AM

Quote:

Originally Posted by KingMort (Post 160594)
OK well maybe some servers have not experienced this, and maybe this has already been posted hopefully not anyway..

Rampage AA you can actually crash zones using it.. If you want to block a certain guild it comes in handy you simply pull the entire zone and use it and blam crashage of the zoneage...


The same also applies for Wizard AOE nukes when killing too many mobs at once...

King

http://www.eqemulator.net/forums/showthread.php?t=26592

I was actually just thinking about this over the past few days, and trying to figure out if there are any opportunities.

I think one big question I have is, are we doing any actual multi-threading in the zone process? As far as I can tell, it doesn't look like it. It basically looks like we're just going down the list of everything that needs to be done throughout the main while loop:
Code:

        while(RunLoops) {
                {        //profiler block to omit the sleep from times
                _ZP(net_main);
               
                //Advance the timer to our current point in time
                Timer::SetCurrentTime();
               
                //process stuff from world
#ifdef CATCH_CRASH
                try{
#endif
                        worldserver.Process();
#ifdef CATCH_CRASH
                }
                catch(...){
                        error = 1;
                        worldserver.Disconnect();
                        worldwasconnected = false;
                }
#endif
                if (!eqsf.IsOpen() && Config->ZonePort!=0) {
                        _log(ZONE__INIT, "Starting EQ Network server on port %d",Config->ZonePort);
                        if (!eqsf.Open(Config->ZonePort)) {
                                _log(ZONE__INIT_ERR, "Failed to open port %d",Config->ZonePort);
                                ZoneConfig::SetZonePort(0);
                                worldserver.Disconnect();
                                worldwasconnected = false;
                        }
                }
               
                //check the factory for any new incoming streams.
                while ((eqss = eqsf.Pop())) {
                        //pull the stream out of the factory and give it to the stream identifier
                        //which will figure out what patch they are running, and set up the dynamic
                        //structures and opcodes for that patch.
                        struct in_addr        in;
                        in.s_addr = eqss->GetRemoteIP();
                        _log(WORLD__CLIENT, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
                        stream_identifier.AddStream(eqss);        //takes the stream
                }
               
                //give the stream identifier a chance to do its work....
                stream_identifier.Process();
               
                //check the stream identifier for any now-identified streams
                while((eqsi = stream_identifier.PopIdentified())) {
                        //now that we know what patch they are running, start up their client object
                        struct in_addr        in;
                        in.s_addr = eqsi->GetRemoteIP();
                        _log(WORLD__CLIENT, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
                        Client* client = new Client(eqsi);
                        entity_list.AddClient(client);
                }
               
               
                //check for timeouts in other threads
                timeout_manager.CheckTimeouts();
               
                if (worldserver.Connected()) {
                        worldwasconnected = true;
                }
                else {
                        if (worldwasconnected && ZoneLoaded)
                                entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
                        worldwasconnected = false;
                }
                if (ZoneLoaded && temp_timer.Check()) {
                        {
                                int8 error2 = 4;
#ifdef CATCH_CRASH
                                try{
#endif
                                        if(net.group_timer.Enabled() && net.group_timer.Check())
                                                entity_list.GroupProcess();
                                        error2 = 99;
                                        if(net.door_timer.Enabled() && net.door_timer.Check())
                                                entity_list.DoorProcess();
                                        error2 = 98;
                                        if(net.object_timer.Enabled() && net.object_timer.Check())
                                                entity_list.ObjectProcess();
                                        error2 = 97;
                                        if(net.corpse_timer.Enabled() && net.corpse_timer.Check())
                                                entity_list.CorpseProcess();
                                        if(net.trap_timer.Enabled() && net.trap_timer.Check())
                                                entity_list.TrapProcess();
                                        if(net.raid_timer.Enabled() && net.raid_timer.Check())
                                                entity_list.RaidProcess();
                                        error2 = 98;
                                        error2 = 96;
                                        entity_list.Process();
                                        error2 = 95;
#ifdef CATCH_CRASH
                                        try{
                                        entity_list.MobProcess();
                                        }
                                        catch(...){
                                                printf("Catching Mob Crash...\n");
                                        }
#else
                                        entity_list.MobProcess();
#endif
                                        error2 = 94;
                                        entity_list.BeaconProcess();
#ifdef CATCH_CRASH
                                }
                                catch(...){
                                        error=error2;
                                }
                                try{
#endif
                                        if (zone) {


                                                zoneprocess= zone->Process();
                                                if (!zoneprocess) {
                                                        Zone::Shutdown();
                                                }
                                        }
#ifdef CATCH_CRASH
                                }
                                catch(...){
                                        error = 2;
                                }
                                try{
#endif
                                        if(quest_timers.Check())
                                                quest_manager.Process();
#ifdef CATCH_CRASH
                                }
                                catch(...){
                                        error = 77777;
                                }
#endif
                        }
                }
                DBAsyncWork* dbaw = 0;
                while ((dbaw = MTdbafq.Pop())) {
                        DispatchFinishedDBAsync(dbaw);
                }
                if (InterserverTimer.Check()
#ifdef CATCH_CRASH
                        && !error
#endif
                        ) {
#ifdef CATCH_CRASH
                        try{
#endif
                                InterserverTimer.Start();
                                database.ping();
                                AsyncLoadVariables(dbasync, &database);
//                                NPC::GetAILevel(true);
                                entity_list.UpdateWho();
                                if (worldserver.TryReconnect() && (!worldserver.Connected()))
                                        worldserver.AsyncConnect();
#ifdef CATCH_CRASH
                        }
                        catch(...)
                        {
                                error = 16;
                                RunLoops = false;
                        }
#endif
                }
#ifdef CATCH_CRASH
                if (error){
                        RunLoops = false;
                }
#endif
#if defined(_EQDEBUG) && defined(DEBUG_PC)
                QueryPerformanceCounter(&tmp3);
                mainloop_time += tmp3.QuadPart - tmp2.QuadPart;
                if (!--tmp0) {
                        tmp0 = 200;
                        printf("Elapsed Tics  : %9.0f (%1.4f sec)\n", (double)mainloop_time, ((double)mainloop_time/tmp.QuadPart));
                        printf("NPCAI Tics    : %9.0f (%1.2f%%)\n", (double)npcai_time, ((double)npcai_time/mainloop_time)*100);
                        printf("FindSpell Tics: %9.0f (%1.2f%%)\n", (double)findspell_time, ((double)findspell_time/mainloop_time)*100);
                        printf("AtkAllowd Tics: %9.0f (%1.2f%%)\n", (double)IsAttackAllowed_time, ((double)IsAttackAllowed_time/mainloop_time)*100);
                        printf("ClientPro Tics: %9.0f (%1.2f%%)\n", (double)clientprocess_time, ((double)clientprocess_time/mainloop_time)*100);
                        printf("ClientAtk Tics: %9.0f (%1.2f%%)\n", (double)clientattack_time, ((double)clientattack_time/mainloop_time)*100);
                        mainloop_time = 0;
                        npcai_time = 0;
                        findspell_time = 0;
                        IsAttackAllowed_time = 0;
                        clientprocess_time = 0;
                        clientattack_time = 0;
                }
#endif
#ifdef EQPROFILE
#ifdef PROFILE_DUMP_TIME
                if(profile_dump_timer.Check()) {
                        DumpZoneProfile();
                }
#endif
#endif
                }        //end extra profiler block
                Sleep(ZoneTimerResolution);
        }

If we threaded different parts of the zone code, including combat & spells, I think we could get to a point where we could keep communication going with the clients, since other communications would process at the same time as the threads for combat, and the clients wouldn't timeout. Not only that, but it would take out a lot of the cause & effect feel of the Emu experience that you don't get on Live (especially with skills, timers, etc).

Anyone have any thoughts or insight, especially if there is some threading in the zone process that I'm not seeing?


All times are GMT -4. The time now is 11:06 PM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.