mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-02 12:22:27 +00:00
Merge git://github.com/EQEmu/Server into Development
This commit is contained in:
commit
44dcf7af7d
@ -1,6 +1,8 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
== 08/24/2014 ==
|
== 08/24/2014 ==
|
||||||
|
Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in.
|
||||||
|
Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...)
|
||||||
Akkadius: Character creation process crash fix and query cleanup
|
Akkadius: Character creation process crash fix and query cleanup
|
||||||
Akkadius: Created `character_lookup` table for applications that mirrors all `character_` table fields minus blob fields for application lookups
|
Akkadius: Created `character_lookup` table for applications that mirrors all `character_` table fields minus blob fields for application lookups
|
||||||
- A 2.4GB character_ table will take 7 seconds to query on a SSD versus .1s on the character_lookup table
|
- A 2.4GB character_ table will take 7 seconds to query on a SSD versus .1s on the character_lookup table
|
||||||
|
|||||||
@ -57,6 +57,7 @@ const std::string vStringFormat(const char* format, va_list args)
|
|||||||
va_copy(tmpargs,args);
|
va_copy(tmpargs,args);
|
||||||
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
||||||
va_end(tmpargs);
|
va_end(tmpargs);
|
||||||
|
output.resize(characters_used);
|
||||||
|
|
||||||
if (characters_used < 0) {
|
if (characters_used < 0) {
|
||||||
// We shouldn't have a format error by this point, but I can't imagine what error we
|
// We shouldn't have a format error by this point, but I can't imagine what error we
|
||||||
@ -72,6 +73,8 @@ const std::string vStringFormat(const char* format, va_list args)
|
|||||||
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
||||||
va_end(tmpargs);
|
va_end(tmpargs);
|
||||||
|
|
||||||
|
output.resize(characters_used);
|
||||||
|
|
||||||
if (characters_used < 0) {
|
if (characters_used < 0) {
|
||||||
// We shouldn't have a format error by this point, but I can't imagine what error we
|
// We shouldn't have a format error by this point, but I can't imagine what error we
|
||||||
// could have by this point. Still, return empty string;
|
// could have by this point. Still, return empty string;
|
||||||
@ -380,6 +383,42 @@ std::string EscapeString(const std::string &s) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EscapeString(const char *src, size_t sz) {
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < sz; ++i) {
|
||||||
|
char c = src[i];
|
||||||
|
switch(c) {
|
||||||
|
case '\x00':
|
||||||
|
ret += "\\x00";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
ret += "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
ret += "\\r";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
ret += "\\\\";
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
ret += "\\'";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
ret += "\\\"";
|
||||||
|
break;
|
||||||
|
case '\x1a':
|
||||||
|
ret += "\\x1a";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret.push_back(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool isAlphaNumeric(const char *text)
|
bool isAlphaNumeric(const char *text)
|
||||||
{
|
{
|
||||||
for (unsigned int charIndex=0; charIndex<strlen(text); charIndex++) {
|
for (unsigned int charIndex=0; charIndex<strlen(text); charIndex++) {
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
const std::string vStringFormat(const char* format, va_list args);
|
const std::string vStringFormat(const char* format, va_list args);
|
||||||
const std::string StringFormat(const char* format, ...);
|
const std::string StringFormat(const char* format, ...);
|
||||||
std::string EscapeString(const std::string &s);
|
std::string EscapeString(const std::string &s);
|
||||||
|
std::string EscapeString(const char *src, size_t sz);
|
||||||
|
|
||||||
const char *MakeLowerString(const char *source);
|
const char *MakeLowerString(const char *source);
|
||||||
|
|
||||||
|
|||||||
@ -7,12 +7,13 @@ SET(tests_sources
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET(tests_headers
|
SET(tests_headers
|
||||||
|
atobool_test.h
|
||||||
fixed_memory_test.h
|
fixed_memory_test.h
|
||||||
fixed_memory_variable_test.h
|
fixed_memory_variable_test.h
|
||||||
|
hextoi_32_64_test.h
|
||||||
ipc_mutex_test.h
|
ipc_mutex_test.h
|
||||||
memory_mapped_file_test.h
|
memory_mapped_file_test.h
|
||||||
atobool_test.h
|
string_util_test.h
|
||||||
hextoi_32_64_test.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "fixed_memory_variable_test.h"
|
#include "fixed_memory_variable_test.h"
|
||||||
#include "atobool_test.h"
|
#include "atobool_test.h"
|
||||||
#include "hextoi_32_64_test.h"
|
#include "hextoi_32_64_test.h"
|
||||||
|
#include "string_util_test.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
try {
|
try {
|
||||||
@ -38,6 +39,7 @@ int main() {
|
|||||||
tests.add(new FixedMemoryVariableHashTest());
|
tests.add(new FixedMemoryVariableHashTest());
|
||||||
tests.add(new atoboolTest());
|
tests.add(new atoboolTest());
|
||||||
tests.add(new hextoi_32_64_Test());
|
tests.add(new hextoi_32_64_Test());
|
||||||
|
tests.add(new StringUtilTest());
|
||||||
tests.run(*output, true);
|
tests.run(*output, true);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
85
tests/string_util_test.h
Normal file
85
tests/string_util_test.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EQEMU_TESTS_STRING_UTIL_H
|
||||||
|
#define __EQEMU_TESTS_STRING_UTIL_H
|
||||||
|
|
||||||
|
#include "cppunit/cpptest.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
|
|
||||||
|
class StringUtilTest : public Test::Suite {
|
||||||
|
typedef void(IPCMutexTest::*TestFunction)(void);
|
||||||
|
public:
|
||||||
|
StringUtilTest() {
|
||||||
|
TEST_ADD(StringUtilTest::StringFormatTest);
|
||||||
|
TEST_ADD(StringUtilTest::EscapeStringTest);
|
||||||
|
TEST_ADD(StringUtilTest::EscapeStringMemoryTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
~StringUtilTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void StringFormatTest() {
|
||||||
|
const char* fmt = "Test: %c %d %4.2f";
|
||||||
|
char c = 'a';
|
||||||
|
int i = 2014;
|
||||||
|
float f = 3.1416;
|
||||||
|
|
||||||
|
auto s = StringFormat(fmt, c, i, f);
|
||||||
|
TEST_ASSERT(s.length() == 17);
|
||||||
|
TEST_ASSERT(s.compare("Test: a 2014 3.14") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EscapeStringTest() {
|
||||||
|
std::string t;
|
||||||
|
t.resize(10);
|
||||||
|
t[0] = 'a';
|
||||||
|
t[1] = 'b';
|
||||||
|
t[2] = 'c';
|
||||||
|
t[3] = '\x00';
|
||||||
|
t[4] = '\n';
|
||||||
|
t[5] = '\r';
|
||||||
|
t[6] = '\\';
|
||||||
|
t[7] = '\'';
|
||||||
|
t[8] = '\"';
|
||||||
|
t[9] = '\x1a';
|
||||||
|
|
||||||
|
auto s = EscapeString(t);
|
||||||
|
TEST_ASSERT(s.compare("abc\\x00\\n\\r\\\\\\'\\\"\\x1a") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EscapeStringMemoryTest() {
|
||||||
|
char t[10] = { 0 };
|
||||||
|
t[0] = 'a';
|
||||||
|
t[1] = 'b';
|
||||||
|
t[2] = 'c';
|
||||||
|
t[3] = '\x00';
|
||||||
|
t[4] = '\n';
|
||||||
|
t[5] = '\r';
|
||||||
|
t[6] = '\\';
|
||||||
|
t[7] = '\'';
|
||||||
|
t[8] = '\"';
|
||||||
|
t[9] = '\x1a';
|
||||||
|
|
||||||
|
auto s = EscapeString(t, 10);
|
||||||
|
TEST_ASSERT(s.compare("abc\\x00\\n\\r\\\\\\'\\\"\\x1a") == 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1598,7 +1598,7 @@ Corpse *EntityList::GetCorpseByName(const char *name)
|
|||||||
|
|
||||||
Spawn2 *EntityList::GetSpawnByID(uint32 id)
|
Spawn2 *EntityList::GetSpawnByID(uint32 id)
|
||||||
{
|
{
|
||||||
if (!zone)
|
if (!zone || !zone->IsLoaded())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
LinkedListIterator<Spawn2 *> iterator(zone->spawn2_list);
|
LinkedListIterator<Spawn2 *> iterator(zone->spawn2_list);
|
||||||
|
|||||||
@ -541,13 +541,40 @@ void NPC::AI_Start(uint32 iMoveDelay) {
|
|||||||
void Mob::AI_Stop() {
|
void Mob::AI_Stop() {
|
||||||
if (!IsAIControlled())
|
if (!IsAIControlled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pAIControlled = false;
|
pAIControlled = false;
|
||||||
|
|
||||||
safe_delete(AIthink_timer);
|
safe_delete(AIthink_timer);
|
||||||
safe_delete(AIwalking_timer);
|
safe_delete(AIwalking_timer);
|
||||||
safe_delete(AImovement_timer);
|
safe_delete(AImovement_timer);
|
||||||
safe_delete(AItarget_check_timer)
|
safe_delete(AItarget_check_timer);
|
||||||
safe_delete(AIscanarea_timer);
|
safe_delete(AIscanarea_timer);
|
||||||
safe_delete(AIfeignremember_timer);
|
safe_delete(AIfeignremember_timer);
|
||||||
|
safe_delete(PathingLOSCheckTimer);
|
||||||
|
safe_delete(PathingRouteUpdateTimerShort);
|
||||||
|
safe_delete(PathingRouteUpdateTimerLong);
|
||||||
|
|
||||||
|
attack_timer.Disable();
|
||||||
|
attack_dw_timer.Disable();
|
||||||
|
ranged_timer.Disable();
|
||||||
|
tic_timer.Disable();
|
||||||
|
mana_timer.Disable();
|
||||||
|
spellend_timer.Disable();
|
||||||
|
projectile_timer.Disable();
|
||||||
|
rewind_timer.Disable();
|
||||||
|
bindwound_timer.Disable();
|
||||||
|
stunned_timer.Disable();
|
||||||
|
spun_timer.Disable();
|
||||||
|
bardsong_timer.Disable();
|
||||||
|
gravity_timer.Disable();
|
||||||
|
viral_timer.Disable();
|
||||||
|
flee_timer.Disable();
|
||||||
|
|
||||||
|
for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) {
|
||||||
|
if (SpecialAbilities[sat].timer)
|
||||||
|
SpecialAbilities[sat].timer->Disable();
|
||||||
|
}
|
||||||
|
|
||||||
hate_list.Wipe();
|
hate_list.Wipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,6 @@ void QueryServ::PlayerLogEvent(int Event_Type, int Character_ID, std::string Eve
|
|||||||
{
|
{
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
"INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))",
|
"INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))",
|
||||||
Event_Type, Character_ID, EscapeString(Event_Desc.c_str()).c_str());
|
Event_Type, Character_ID, EscapeString(Event_Desc).c_str());
|
||||||
SendQuery(query);
|
SendQuery(query);
|
||||||
}
|
}
|
||||||
@ -600,8 +600,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) {
|
QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) {
|
||||||
|
if(!zone || !zone->IsLoaded())
|
||||||
if(!zone)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
//first look for /quests/zone/player_v[instance_version].ext (precedence)
|
//first look for /quests/zone/player_v[instance_version].ext (precedence)
|
||||||
|
|||||||
@ -718,11 +718,24 @@ void Zone::DBAWComplete(uint8 workpt_b1, DBAsyncWork* dbaw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Zone::IsLoaded() {
|
||||||
|
return ZoneLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
void Zone::Shutdown(bool quite)
|
void Zone::Shutdown(bool quite)
|
||||||
{
|
{
|
||||||
if (!ZoneLoaded)
|
if (!ZoneLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::list<Mob*> mob_list;
|
||||||
|
entity_list.GetMobList(mob_list);
|
||||||
|
std::list<Mob*>::iterator mob_itr = mob_list.begin();
|
||||||
|
while (mob_itr != mob_list.end()) {
|
||||||
|
Mob* mob_inst = *mob_itr;
|
||||||
|
mob_inst->AI_Stop();
|
||||||
|
++mob_itr;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<uint32,NPCType *>::iterator itr;
|
std::map<uint32,NPCType *>::iterator itr;
|
||||||
while(zone->npctable.size()) {
|
while(zone->npctable.size()) {
|
||||||
itr=zone->npctable.begin();
|
itr=zone->npctable.begin();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user