mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into integration/multi-tenancy-expansions-repository
This commit is contained in:
commit
2b1b786f02
17
.gitignore
vendored
17
.gitignore
vendored
@ -37,4 +37,19 @@ perl/
|
||||
submodules/*
|
||||
cmake-build-debug/
|
||||
|
||||
.nfs.*
|
||||
.nfs.*
|
||||
|
||||
# Visual Studio and CMAKE Generated Files
|
||||
/.vs/
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.cmake
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.dir/
|
||||
libs/
|
||||
bin/
|
||||
/Win32
|
||||
/client_files/**/CMakeFiles/
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# EQEmulator Core Server
|
||||
|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|
||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||
|:---:|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) |
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||
|
||||
***
|
||||
|
||||
|
||||
@ -78,6 +78,7 @@ SET(common_sources
|
||||
unix.cpp
|
||||
platform.cpp
|
||||
json/jsoncpp.cpp
|
||||
namegenerator/namegen.cpp
|
||||
net/console_server.cpp
|
||||
net/console_server_connection.cpp
|
||||
net/crc32.cpp
|
||||
@ -562,6 +563,7 @@ SET(common_headers
|
||||
event/timer.h
|
||||
json/json.h
|
||||
json/json-forwards.h
|
||||
namegenerator/namegen.h
|
||||
net/console_server.h
|
||||
net/console_server_connection.h
|
||||
net/crc32.h
|
||||
|
||||
@ -870,6 +870,38 @@ void Database::GetCharName(uint32 char_id, char* name) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* Database::GetCharNameByID(uint32 char_id) {
|
||||
std::string query = fmt::format("SELECT `name` FROM `character_data` WHERE id = {}", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return row[0];
|
||||
}
|
||||
|
||||
const char* Database::GetNPCNameByID(uint32 npc_id) {
|
||||
std::string query = fmt::format("SELECT `name` FROM `npc_types` WHERE id = {}", npc_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return row[0];
|
||||
}
|
||||
|
||||
bool Database::LoadVariables() {
|
||||
auto results = QueryDatabase(StringFormat("SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache.last_update));
|
||||
|
||||
@ -2318,3 +2350,4 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -137,6 +137,8 @@ public:
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
const char *GetCharNameByID(uint32 char_id);
|
||||
const char *GetNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
@ -50,7 +50,11 @@ std::string DatabaseDumpService::execute(const std::string &cmd, bool return_res
|
||||
const char *file_name = "db-exec-result.txt";
|
||||
|
||||
if (return_result) {
|
||||
#ifdef _WINDOWS
|
||||
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||
#else
|
||||
std::system((cmd + " > " + file_name).c_str());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
std::system((cmd).c_str());
|
||||
@ -95,7 +99,7 @@ bool DatabaseDumpService::IsTarAvailable()
|
||||
*/
|
||||
bool DatabaseDumpService::Is7ZipAvailable()
|
||||
{
|
||||
std::string version_output = execute("7z -help");
|
||||
std::string version_output = execute("7z --help");
|
||||
|
||||
return version_output.find("7-Zip") != std::string::npos;
|
||||
}
|
||||
@ -396,9 +400,8 @@ void DatabaseDumpService::Dump()
|
||||
else if (Is7ZipAvailable()) {
|
||||
execute(
|
||||
fmt::format(
|
||||
"7z a -t7z {}.zip -C {} {}.sql",
|
||||
"7z a -t7z {}.zip {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetSetDumpPath(),
|
||||
GetDumpFileNameWithPath()
|
||||
)
|
||||
);
|
||||
|
||||
@ -25,6 +25,10 @@ namespace EQ
|
||||
uv_run(&m_loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
uv_stop(&m_loop);
|
||||
}
|
||||
|
||||
uv_loop_t* Handle() { return &m_loop; }
|
||||
|
||||
private:
|
||||
|
||||
522
common/namegenerator/namegen.cpp
Normal file
522
common/namegenerator/namegen.cpp
Normal file
@ -0,0 +1,522 @@
|
||||
/**
|
||||
*
|
||||
* @file A fantasy name generator library.
|
||||
* @version 1.0.1
|
||||
* @license Public Domain
|
||||
* @author German M. Bravo (Kronuz)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "namegen.h"
|
||||
|
||||
#include <algorithm> // for move, reverse
|
||||
#include <chrono> // for rng seed
|
||||
#include <cwchar> // for size_t, mbsrtowcs, wcsrtombs
|
||||
#include <cwctype> // for towupper
|
||||
#include <memory> // for make_unique
|
||||
#include <random> // for mt19937, uniform_real_distribution
|
||||
#include <stdexcept> // for invalid_argument, out_of_range
|
||||
|
||||
|
||||
using namespace NameGen;
|
||||
|
||||
|
||||
static std::mt19937 rng(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
||||
|
||||
|
||||
// https://isocpp.org/wiki/faq/ctors#static-init-order
|
||||
// Avoid the "static initialization order fiasco"
|
||||
const std::unordered_map<std::string, const std::vector<std::string>>& Generator::SymbolMap()
|
||||
{
|
||||
static auto* const symbols = new std::unordered_map<std::string, const std::vector<std::string>>({
|
||||
{
|
||||
"s", {
|
||||
"ach", "ack", "ad", "age", "ald", "ale", "an", "ang", "ar", "ard",
|
||||
"as", "ash", "at", "ath", "augh", "aw", "ban", "bel", "bur", "cer",
|
||||
"cha", "che", "dan", "dar", "del", "den", "dra", "dyn", "ech", "eld",
|
||||
"elm", "em", "en", "end", "eng", "enth", "er", "ess", "est", "et",
|
||||
"gar", "gha", "hat", "hin", "hon", "ia", "ight", "ild", "im", "ina",
|
||||
"ine", "ing", "ir", "is", "iss", "it", "kal", "kel", "kim", "kin",
|
||||
"ler", "lor", "lye", "mor", "mos", "nal", "ny", "nys", "old", "om",
|
||||
"on", "or", "orm", "os", "ough", "per", "pol", "qua", "que", "rad",
|
||||
"rak", "ran", "ray", "ril", "ris", "rod", "roth", "ryn", "sam",
|
||||
"say", "ser", "shy", "skel", "sul", "tai", "tan", "tas", "ther",
|
||||
"tia", "tin", "ton", "tor", "tur", "um", "und", "unt", "urn", "usk",
|
||||
"ust", "ver", "ves", "vor", "war", "wor", "yer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"v", {
|
||||
"a", "e", "i", "o", "u", "y"
|
||||
}
|
||||
},
|
||||
{
|
||||
"V", {
|
||||
"a", "e", "i", "o", "u", "y", "ae", "ai", "au", "ay", "ea", "ee",
|
||||
"ei", "eu", "ey", "ia", "ie", "oe", "oi", "oo", "ou", "ui"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c", {
|
||||
"b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r",
|
||||
"s", "t", "v", "w", "x", "y", "z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"B", {
|
||||
"b", "bl", "br", "c", "ch", "chr", "cl", "cr", "d", "dr", "f", "g",
|
||||
"h", "j", "k", "l", "ll", "m", "n", "p", "ph", "qu", "r", "rh", "s",
|
||||
"sch", "sh", "sl", "sm", "sn", "st", "str", "sw", "t", "th", "thr",
|
||||
"tr", "v", "w", "wh", "y", "z", "zh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"C", {
|
||||
"b", "c", "ch", "ck", "d", "f", "g", "gh", "h", "k", "l", "ld", "ll",
|
||||
"lt", "m", "n", "nd", "nn", "nt", "p", "ph", "q", "r", "rd", "rr",
|
||||
"rt", "s", "sh", "ss", "st", "t", "th", "v", "w", "y", "z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"i", {
|
||||
"air", "ankle", "ball", "beef", "bone", "bum", "bumble", "bump",
|
||||
"cheese", "clod", "clot", "clown", "corn", "dip", "dolt", "doof",
|
||||
"dork", "dumb", "face", "finger", "foot", "fumble", "goof",
|
||||
"grumble", "head", "knock", "knocker", "knuckle", "loaf", "lump",
|
||||
"lunk", "meat", "muck", "munch", "nit", "numb", "pin", "puff",
|
||||
"skull", "snark", "sneeze", "thimble", "twerp", "twit", "wad",
|
||||
"wimp", "wipe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"m", {
|
||||
"baby", "booble", "bunker", "cuddle", "cuddly", "cutie", "doodle",
|
||||
"foofie", "gooble", "honey", "kissie", "lover", "lovey", "moofie",
|
||||
"mooglie", "moopie", "moopsie", "nookum", "poochie", "poof",
|
||||
"poofie", "pookie", "schmoopie", "schnoogle", "schnookie",
|
||||
"schnookum", "smooch", "smoochie", "smoosh", "snoogle", "snoogy",
|
||||
"snookie", "snookum", "snuggy", "sweetie", "woogle", "woogy",
|
||||
"wookie", "wookum", "wuddle", "wuddly", "wuggy", "wunny"
|
||||
}
|
||||
},
|
||||
{
|
||||
"M", {
|
||||
"boo", "bunch", "bunny", "cake", "cakes", "cute", "darling",
|
||||
"dumpling", "dumplings", "face", "foof", "goo", "head", "kin",
|
||||
"kins", "lips", "love", "mush", "pie", "poo", "pooh", "pook", "pums"
|
||||
}
|
||||
},
|
||||
{
|
||||
"D", {
|
||||
"b", "bl", "br", "cl", "d", "f", "fl", "fr", "g", "gh", "gl", "gr",
|
||||
"h", "j", "k", "kl", "m", "n", "p", "th", "w"
|
||||
}
|
||||
},
|
||||
{
|
||||
"d", {
|
||||
"elch", "idiot", "ob", "og", "ok", "olph", "olt", "omph", "ong",
|
||||
"onk", "oo", "oob", "oof", "oog", "ook", "ooz", "org", "ork", "orm",
|
||||
"oron", "ub", "uck", "ug", "ulf", "ult", "um", "umb", "ump", "umph",
|
||||
"un", "unb", "ung", "unk", "unph", "unt", "uzz"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return *symbols;
|
||||
}
|
||||
|
||||
Generator::Generator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Generator::Generator(std::vector<std::unique_ptr<Generator>>&& generators_) :
|
||||
generators(std::move(generators_))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
size_t Generator::combinations()
|
||||
{
|
||||
size_t total = 1;
|
||||
for (auto& g : generators) {
|
||||
total *= g->combinations();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
size_t Generator::min()
|
||||
{
|
||||
size_t final = 0;
|
||||
for (auto& g : generators) {
|
||||
final += g->min();
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
|
||||
size_t Generator::max()
|
||||
{
|
||||
size_t final = 0;
|
||||
for (auto& g : generators) {
|
||||
final += g->max();
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
|
||||
std::string Generator::toString() {
|
||||
std::string str;
|
||||
for (auto& g : generators) {
|
||||
str.append(g->toString());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
void Generator::add(std::unique_ptr<Generator>&& g)
|
||||
{
|
||||
generators.push_back(std::move(g));
|
||||
}
|
||||
|
||||
|
||||
Random::Random()
|
||||
{
|
||||
}
|
||||
|
||||
Random::Random(std::vector<std::unique_ptr<Generator>>&& generators_) :
|
||||
Generator(std::move(generators_))
|
||||
{
|
||||
}
|
||||
|
||||
size_t Random::combinations()
|
||||
{
|
||||
size_t total = 0;
|
||||
for (auto& g : generators) {
|
||||
total += g->combinations();
|
||||
}
|
||||
return total ? total : 1;
|
||||
}
|
||||
|
||||
size_t Random::min()
|
||||
{
|
||||
size_t final = -1;
|
||||
for (auto& g : generators) {
|
||||
size_t current = g->min();
|
||||
if (current < final) {
|
||||
final = current;
|
||||
}
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
size_t Random::max()
|
||||
{
|
||||
size_t final = 0;
|
||||
for (auto& g : generators) {
|
||||
size_t current = g->max();
|
||||
if (current > final) {
|
||||
final = current;
|
||||
}
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
|
||||
std::string Random::toString()
|
||||
{
|
||||
if (!generators.size()) {
|
||||
return "";
|
||||
}
|
||||
std::uniform_real_distribution<double> distribution(0, generators.size() - 1);
|
||||
int rnd = distribution(rng) + 0.5;
|
||||
return generators[rnd]->toString();
|
||||
}
|
||||
|
||||
|
||||
Sequence::Sequence()
|
||||
{
|
||||
}
|
||||
|
||||
Sequence::Sequence(std::vector<std::unique_ptr<Generator>>&& generators_) :
|
||||
Generator(std::move(generators_))
|
||||
{
|
||||
}
|
||||
|
||||
Literal::Literal(const std::string &value_) :
|
||||
value(value_)
|
||||
{
|
||||
}
|
||||
|
||||
size_t Literal::combinations()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t Literal::min()
|
||||
{
|
||||
return value.size();
|
||||
}
|
||||
|
||||
size_t Literal::max()
|
||||
{
|
||||
return value.size();
|
||||
}
|
||||
|
||||
std::string Literal::toString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
Reverser::Reverser(std::unique_ptr<Generator>&& g)
|
||||
{
|
||||
add(std::move(g));
|
||||
}
|
||||
|
||||
|
||||
std::string Reverser::toString()
|
||||
{
|
||||
std::wstring str = towstring(Generator::toString());
|
||||
std::reverse(str.begin(), str.end());
|
||||
return tostring(str);
|
||||
}
|
||||
|
||||
Capitalizer::Capitalizer(std::unique_ptr<Generator>&& g)
|
||||
{
|
||||
add(std::move(g));
|
||||
}
|
||||
|
||||
std::string Capitalizer::toString()
|
||||
{
|
||||
std::wstring str = towstring(Generator::toString());
|
||||
str[0] = std::towupper(str[0]);
|
||||
return tostring(str);
|
||||
}
|
||||
|
||||
|
||||
Collapser::Collapser(std::unique_ptr<Generator>&& g)
|
||||
{
|
||||
add(std::move(g));
|
||||
}
|
||||
|
||||
std::string Collapser::toString()
|
||||
{
|
||||
std::wstring str = towstring(Generator::toString());
|
||||
std::wstring out;
|
||||
int cnt = 0;
|
||||
wchar_t pch = L'\0';
|
||||
for (auto ch : str) {
|
||||
if (ch == pch) {
|
||||
cnt++;
|
||||
} else {
|
||||
cnt = 0;
|
||||
}
|
||||
int mch = 2;
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 'j':
|
||||
case 'q':
|
||||
case 'u':
|
||||
case 'v':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'y':
|
||||
mch = 1;
|
||||
}
|
||||
if (cnt < mch) {
|
||||
out.push_back(ch);
|
||||
}
|
||||
pch = ch;
|
||||
}
|
||||
return tostring(out);
|
||||
}
|
||||
|
||||
|
||||
Generator::Generator(const std::string &pattern, bool collapse_triples) {
|
||||
std::unique_ptr<Generator> last;
|
||||
|
||||
std::stack<std::unique_ptr<Group>> stack;
|
||||
std::unique_ptr<Group> top = std::unique_ptr<GroupSymbol>();
|
||||
|
||||
for (auto c : pattern) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
stack.push(std::move(top));
|
||||
top = std::unique_ptr<GroupSymbol>();
|
||||
break;
|
||||
case '(':
|
||||
stack.push(std::move(top));
|
||||
top = std::unique_ptr<GroupLiteral>();
|
||||
break;
|
||||
case '>':
|
||||
case ')':
|
||||
if (stack.size() == 0) {
|
||||
throw std::invalid_argument("Unbalanced brackets");
|
||||
} else if (c == '>' && top->type != group_types::symbol) {
|
||||
throw std::invalid_argument("Unexpected '>' in pattern");
|
||||
} else if (c == ')' && top->type != group_types::literal) {
|
||||
throw std::invalid_argument("Unexpected ')' in pattern");
|
||||
}
|
||||
last = top->produce();
|
||||
top = std::move(stack.top());
|
||||
stack.pop();
|
||||
top->add(std::move(last));
|
||||
break;
|
||||
case '|':
|
||||
top->split();
|
||||
break;
|
||||
case '!':
|
||||
if (top->type == group_types::symbol) {
|
||||
top->wrap(wrappers::capitalizer);
|
||||
} else {
|
||||
top->add(c);
|
||||
}
|
||||
break;
|
||||
case '~':
|
||||
if (top->type == group_types::symbol) {
|
||||
top->wrap(wrappers::reverser);
|
||||
} else {
|
||||
top->add(c);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
top->add(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.size() != 0) {
|
||||
throw std::invalid_argument("Missing closing bracket");
|
||||
}
|
||||
|
||||
std::unique_ptr<Generator> g = top->produce();
|
||||
if (collapse_triples) {
|
||||
g = std::unique_ptr<Collapser>(new Collapser(std::move(g)));
|
||||
}
|
||||
add(std::move(g));
|
||||
}
|
||||
|
||||
|
||||
Generator::Group::Group(group_types_t type_) :
|
||||
type(type_)
|
||||
{
|
||||
}
|
||||
|
||||
void Generator::Group::add(std::unique_ptr<Generator>&& g)
|
||||
{
|
||||
while (!wrappers.empty()) {
|
||||
switch (wrappers.top()) {
|
||||
case reverser:
|
||||
g = std::unique_ptr<Reverser>(new Reverser(std::move(g)));
|
||||
break;
|
||||
case capitalizer:
|
||||
g = std::unique_ptr<Capitalizer>(new Capitalizer(std::move(g)));
|
||||
break;
|
||||
}
|
||||
wrappers.pop();
|
||||
}
|
||||
if (set.size() == 0) {
|
||||
set.push_back(std::unique_ptr<Sequence>());
|
||||
}
|
||||
set.back()->add(std::move(g));
|
||||
}
|
||||
|
||||
void Generator::Group::add(char c)
|
||||
{
|
||||
std::string value(1, c);
|
||||
std::unique_ptr<Generator> g = std::unique_ptr<Random>();
|
||||
g->add(std::unique_ptr<Literal>(new Literal(value)));
|
||||
Group::add(std::move(g));
|
||||
}
|
||||
|
||||
std::unique_ptr<Generator> Generator::Group::produce()
|
||||
{
|
||||
switch (set.size()) {
|
||||
case 0:
|
||||
return std::unique_ptr<Literal>(new Literal(""));
|
||||
case 1:
|
||||
return std::move(*set.begin());
|
||||
default:
|
||||
return std::unique_ptr<Random>(new Random(std::move(set)));
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::Group::split()
|
||||
{
|
||||
if (set.size() == 0) {
|
||||
set.push_back(std::unique_ptr<Sequence>());
|
||||
}
|
||||
set.push_back(std::unique_ptr<Sequence>());
|
||||
}
|
||||
|
||||
void Generator::Group::wrap(wrappers_t type)
|
||||
{
|
||||
wrappers.push(type);
|
||||
}
|
||||
|
||||
Generator::GroupSymbol::GroupSymbol() :
|
||||
Group(group_types::symbol)
|
||||
{
|
||||
}
|
||||
|
||||
void Generator::GroupSymbol::add(char c)
|
||||
{
|
||||
std::string value(1, c);
|
||||
std::unique_ptr<Generator> g = std::unique_ptr<Random>();
|
||||
try {
|
||||
static const auto& symbols = SymbolMap();
|
||||
for (const auto& s : symbols.at(value)) {
|
||||
g->add(std::unique_ptr<Literal>(new Literal(s)));
|
||||
}
|
||||
} catch (const std::out_of_range&) {
|
||||
g->add(std::unique_ptr<Literal>(new Literal(value)));
|
||||
}
|
||||
Group::add(std::move(g));
|
||||
}
|
||||
|
||||
Generator::GroupLiteral::GroupLiteral() :
|
||||
Group(group_types::literal)
|
||||
{
|
||||
}
|
||||
|
||||
std::wstring towstring(const std::string & s)
|
||||
{
|
||||
const char *cs = s.c_str();
|
||||
const size_t wn = std::mbsrtowcs(nullptr, &cs, 0, nullptr);
|
||||
|
||||
if (wn == static_cast<size_t>(-1)) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::vector<wchar_t> buf(wn);
|
||||
cs = s.c_str();
|
||||
const size_t wn_again = std::mbsrtowcs(buf.data(), &cs, wn, nullptr);
|
||||
|
||||
if (wn_again == static_cast<size_t>(-1)) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
return std::wstring(buf.data(), wn);
|
||||
}
|
||||
|
||||
std::string tostring(const std::wstring & s)
|
||||
{
|
||||
const wchar_t *cs = s.c_str();
|
||||
const size_t wn = std::wcsrtombs(nullptr, &cs, 0, nullptr);
|
||||
|
||||
if (wn == static_cast<size_t>(-1)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::vector<char> buf(wn);
|
||||
const size_t wn_again = std::wcsrtombs(buf.data(), &cs, wn, nullptr);
|
||||
|
||||
if (wn_again == static_cast<size_t>(-1)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return std::string(buf.data(), wn);
|
||||
}
|
||||
269
common/namegenerator/namegen.h
Normal file
269
common/namegenerator/namegen.h
Normal file
@ -0,0 +1,269 @@
|
||||
/**
|
||||
*
|
||||
* @file A fantasy name generator library.
|
||||
* @version 1.0.1
|
||||
* @license Public Domain
|
||||
* @author German M. Bravo (Kronuz)
|
||||
*
|
||||
* This library is designed after the RinkWorks Fantasy Name Generator.
|
||||
* @see http://www.rinkworks.com/namegen/
|
||||
*
|
||||
* @example
|
||||
* NameGen::Generator generator("sV'i");
|
||||
* generator.toString(); // Returns a new name each call with produce()
|
||||
* // => "entheu'loaf"
|
||||
*
|
||||
* ## Pattern Syntax
|
||||
*
|
||||
* The compile() function creates a name generator based on an input
|
||||
* pattern. The letters s, v, V, c, B, C, i, m, M, D, and d represent
|
||||
* different types of random replacements. Everything else is produced
|
||||
* literally.
|
||||
*
|
||||
* s - generic syllable
|
||||
* v - vowel
|
||||
* V - vowel or vowel combination
|
||||
* c - consonant
|
||||
* B - consonant or consonant combination suitable for beginning a word
|
||||
* C - consonant or consonant combination suitable anywhere in a word
|
||||
* i - insult
|
||||
* m - mushy name
|
||||
* M - mushy name ending
|
||||
* D - consonant suited for a stupid person's name
|
||||
* d - syllable suited for a stupid person's name (begins with a vowel)
|
||||
*
|
||||
* All characters between parenthesis () are produced literally. For
|
||||
* example, the pattern "s(dim)", produces a random generic syllable
|
||||
* followed by "dim".
|
||||
*
|
||||
* Characters between angle brackets <> produce patterns from the table
|
||||
* above. Imagine the entire pattern is wrapped in one of these.
|
||||
*
|
||||
* In both types of groupings, a vertical bar | denotes a random
|
||||
* choice. Empty groups are allowed. For example, "(foo|bar)" produces
|
||||
* either "foo" or "bar". The pattern "<c|v|>" produces a constant,
|
||||
* vowel, or nothing at all.
|
||||
*
|
||||
* An exclamation point ! means to capitalize the component that
|
||||
* follows it. For example, "!(foo)" will produce "Foo" and "v!s" will
|
||||
* produce a lowercase vowel followed by a capitalized syllable, like
|
||||
* "eRod".
|
||||
*
|
||||
* A tilde ~ means to reverse the letters of the component that
|
||||
* follows it. For example, "~(foo)" will produce "oof". To reverse an
|
||||
* entire template, wrap it in brackets. For example, to reverse
|
||||
* "sV'i" as a whole use "~<sV'i>". The template "~sV'i" will only
|
||||
* reverse the initial syllable.
|
||||
*
|
||||
* ## Internals
|
||||
*
|
||||
* A name generator is anything with a toString() method, including,
|
||||
* importantly, strings themselves. The generator constructors
|
||||
* (Random, Sequence) perform additional optimizations when *not* used
|
||||
* with the `new` keyword: they may pass through a provided generator,
|
||||
* combine provided generators, or even return a simple string.
|
||||
*
|
||||
* New pattern symbols added to Generator.symbols will automatically
|
||||
* be used by the compiler.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <iosfwd> // for wstring
|
||||
#include <memory> // for unique_ptr
|
||||
#include <stack> // for stack
|
||||
#include <string> // for string
|
||||
#include <unordered_map> // for unordered_map
|
||||
#include <vector> // for vector
|
||||
|
||||
|
||||
namespace NameGen {
|
||||
|
||||
// Middle Earth
|
||||
#define MIDDLE_EARTH "(bil|bal|ban|hil|ham|hal|hol|hob|wil|me|or|ol|od|gor|for|fos|tol|ar|fin|ere|leo|vi|bi|bren|thor)(|go|orbis|apol|adur|mos|ri|i|na|ole|n)(|tur|axia|and|bo|gil|bin|bras|las|mac|grim|wise|l|lo|fo|co|ra|via|da|ne|ta|y|wen|thiel|phin|dir|dor|tor|rod|on|rdo|dis)"
|
||||
|
||||
// Japanese Names (Constrained)
|
||||
#define JAPANESE_NAMES_CONSTRAINED "(aka|aki|bashi|gawa|kawa|furu|fuku|fuji|hana|hara|haru|hashi|hira|hon|hoshi|ichi|iwa|kami|kawa|ki|kita|kuchi|kuro|marui|matsu|miya|mori|moto|mura|nabe|naka|nishi|no|da|ta|o|oo|oka|saka|saki|sawa|shita|shima|i|suzu|taka|take|to|toku|toyo|ue|wa|wara|wata|yama|yoshi|kei|ko|zawa|zen|sen|ao|gin|kin|ken|shiro|zaki|yuki|asa)(||||||||||bashi|gawa|kawa|furu|fuku|fuji|hana|hara|haru|hashi|hira|hon|hoshi|chi|wa|ka|kami|kawa|ki|kita|kuchi|kuro|marui|matsu|miya|mori|moto|mura|nabe|naka|nishi|no|da|ta|o|oo|oka|saka|saki|sawa|shita|shima|suzu|taka|take|to|toku|toyo|ue|wa|wara|wata|yama|yoshi|kei|ko|zawa|zen|sen|ao|gin|kin|ken|shiro|zaki|yuki|sa)"
|
||||
|
||||
// Japanese Names (Diverse)
|
||||
#define JAPANESE_NAMES_DIVERSE "(a|i|u|e|o|||||)(ka|ki|ki|ku|ku|ke|ke|ko|ko|sa|sa|sa|shi|shi|shi|su|su|se|so|ta|ta|chi|chi|tsu|te|to|na|ni|ni|nu|nu|ne|no|no|ha|hi|fu|fu|he|ho|ma|ma|ma|mi|mi|mi|mu|mu|mu|mu|me|mo|mo|mo|ya|yu|yu|yu|yo|ra|ra|ra|ri|ru|ru|ru|re|ro|ro|ro|wa|wa|wa|wa|wo|wo)(ka|ki|ki|ku|ku|ke|ke|ko|ko|sa|sa|sa|shi|shi|shi|su|su|se|so|ta|ta|chi|chi|tsu|te|to|na|ni|ni|nu|nu|ne|no|no|ha|hi|fu|fu|he|ho|ma|ma|ma|mi|mi|mi|mu|mu|mu|mu|me|mo|mo|mo|ya|yu|yu|yu|yo|ra|ra|ra|ri|ru|ru|ru|re|ro|ro|ro|wa|wa|wa|wa|wo|wo)(|(ka|ki|ki|ku|ku|ke|ke|ko|ko|sa|sa|sa|shi|shi|shi|su|su|se|so|ta|ta|chi|chi|tsu|te|to|na|ni|ni|nu|nu|ne|no|no|ha|hi|fu|fu|he|ho|ma|ma|ma|mi|mi|mi|mu|mu|mu|mu|me|mo|mo|mo|ya|yu|yu|yu|yo|ra|ra|ra|ri|ru|ru|ru|re|ro|ro|ro|wa|wa|wa|wa|wo|wo)|(ka|ki|ki|ku|ku|ke|ke|ko|ko|sa|sa|sa|shi|shi|shi|su|su|se|so|ta|ta|chi|chi|tsu|te|to|na|ni|ni|nu|nu|ne|no|no|ha|hi|fu|fu|he|ho|ma|ma|ma|mi|mi|mi|mu|mu|mu|mu|me|mo|mo|mo|ya|yu|yu|yu|yo|ra|ra|ra|ri|ru|ru|ru|re|ro|ro|ro|wa|wa|wa|wa|wo|wo)(|(ka|ki|ki|ku|ku|ke|ke|ko|ko|sa|sa|sa|shi|shi|shi|su|su|se|so|ta|ta|chi|chi|tsu|te|to|na|ni|ni|nu|nu|ne|no|no|ha|hi|fu|fu|he|ho|ma|ma|ma|mi|mi|mi|mu|mu|mu|mu|me|mo|mo|mo|ya|yu|yu|yu|yo|ra|ra|ra|ri|ru|ru|ru|re|ro|ro|ro|wa|wa|wa|wa|wo|wo)))(|||n)"
|
||||
|
||||
// Chinese Names
|
||||
#define CHINESE_NAMES "(zh|x|q|sh|h)(ao|ian|uo|ou|ia)(|(l|w|c|p|b|m)(ao|ian|uo|ou|ia)(|n)|-(l|w|c|p|b|m)(ao|ian|uo|ou|ia)(|(d|j|q|l)(a|ai|iu|ao|i)))"
|
||||
|
||||
// Greek Names
|
||||
#define GREEK_NAMES "<s<v|V>(tia)|s<v|V>(os)|B<v|V>c(ios)|B<v|V><c|C>v(ios|os)>"
|
||||
|
||||
// Hawaiian Names (1)
|
||||
#define HAWAIIAN_NAMES_1 "((h|k|l|m|n|p|w|')|)(a|e|i|o|u)((h|k|l|m|n|p|w|')|)(a|e|i|o|u)(((h|k|l|m|n|p|w|')|)(a|e|i|o|u)|)(((h|k|l|m|n|p|w|')|)(a|e|i|o|u)|)(((h|k|l|m|n|p|w|')|)(a|e|i|o|u)|)(((h|k|l|m|n|p|w|')|)(a|e|i|o|u)|)"
|
||||
|
||||
// Hawaiian Names (2)
|
||||
#define HAWAIIAN_NAMES_2 "((h|k|l|m|n|p|w|)(a|e|i|o|u|a'|e'|i'|o'|u'|ae|ai|ao|au|oi|ou|eu|ei)(k|l|m|n|p|)|)(h|k|l|m|n|p|w|)(a|e|i|o|u|a'|e'|i'|o'|u'|ae|ai|ao|au|oi|ou|eu|ei)(k|l|m|n|p|)"
|
||||
|
||||
// Old Latin Place Names
|
||||
#define OLD_LATIN_PLACE_NAMES "sv(nia|lia|cia|sia)"
|
||||
|
||||
// Dragons (Pern)
|
||||
#define DRAGONS_PERN "<<s|ss>|<VC|vC|B|BVs|Vs>><v|V|v|<v(l|n|r)|vc>>(th)"
|
||||
|
||||
// Dragon Riders
|
||||
#define DRAGON_RIDERS "c'<s|cvc>"
|
||||
|
||||
// Pokemon
|
||||
#define POKEMON "<i|s>v(mon|chu|zard|rtle)"
|
||||
|
||||
// Fantasy (Vowels, R, etc.)
|
||||
#define FANTASY_VOWELS_R "(|(<B>|s|h|ty|ph|r))(i|ae|ya|ae|eu|ia|i|eo|ai|a)(lo|la|sri|da|dai|the|sty|lae|due|li|lly|ri|na|ral|sur|rith)(|(su|nu|sti|llo|ria|))(|(n|ra|p|m|lis|cal|deu|dil|suir|phos|ru|dru|rin|raap|rgue))"
|
||||
|
||||
// Fantasy (S, A, etc.)
|
||||
#define FANTASY_S_A "(cham|chan|jisk|lis|frich|isk|lass|mind|sond|sund|ass|chad|lirt|und|mar|lis|il|<BVC>)(jask|ast|ista|adar|irra|im|ossa|assa|osia|ilsa|<vCv>)(|(an|ya|la|sta|sda|sya|st|nya))"
|
||||
|
||||
// Fantasy (H, L, etc.)
|
||||
#define FANTASY_H_L "(ch|ch't|sh|cal|val|ell|har|shar|shal|rel|laen|ral|jh't|alr|ch|ch't|av)(|(is|al|ow|ish|ul|el|ar|iel))(aren|aeish|aith|even|adur|ulash|alith|atar|aia|erin|aera|ael|ira|iel|ahur|ishul)"
|
||||
|
||||
// Fantasy (N, L, etc.)
|
||||
#define FANTASY_N_L "(ethr|qil|mal|er|eal|far|fil|fir|ing|ind|il|lam|quel|quar|quan|qar|pal|mal|yar|um|ard|enn|ey)(|(<vc>|on|us|un|ar|as|en|ir|ur|at|ol|al|an))(uard|wen|arn|on|il|ie|on|iel|rion|rian|an|ista|rion|rian|cil|mol|yon)"
|
||||
|
||||
// Fantasy (K, N, etc.)
|
||||
#define FANTASY_K_N "(taith|kach|chak|kank|kjar|rak|kan|kaj|tach|rskal|kjol|jok|jor|jad|kot|kon|knir|kror|kol|tul|rhaok|rhak|krol|jan|kag|ryr)(<vc>|in|or|an|ar|och|un|mar|yk|ja|arn|ir|ros|ror)(|(mund|ard|arn|karr|chim|kos|rir|arl|kni|var|an|in|ir|a|i|as))"
|
||||
|
||||
// Fantasy (J, G, Z, etc.)
|
||||
#define FANTASY_J_G_Z "(aj|ch|etz|etzl|tz|kal|gahn|kab|aj|izl|ts|jaj|lan|kach|chaj|qaq|jol|ix|az|biq|nam)(|(<vc>|aw|al|yes|il|ay|en|tom||oj|im|ol|aj|an|as))(aj|am|al|aqa|ende|elja|ich|ak|ix|in|ak|al|il|ek|ij|os|al|im)"
|
||||
|
||||
// Fantasy (K, J, Y, etc.)
|
||||
#define FANTASY_K_J_Y "(yi|shu|a|be|na|chi|cha|cho|ksa|yi|shu)(th|dd|jj|sh|rr|mk|n|rk|y|jj|th)(us|ash|eni|akra|nai|ral|ect|are|el|urru|aja|al|uz|ict|arja|ichi|ural|iru|aki|esh)"
|
||||
|
||||
// Fantasy (S, E, etc.)
|
||||
#define FANTASY_S_E "(syth|sith|srr|sen|yth|ssen|then|fen|ssth|kel|syn|est|bess|inth|nen|tin|cor|sv|iss|ith|sen|slar|ssil|sthen|svis|s|ss|s|ss)(|(tys|eus|yn|of|es|en|ath|elth|al|ell|ka|ith|yrrl|is|isl|yr|ast|iy))(us|yn|en|ens|ra|rg|le|en|ith|ast|zon|in|yn|ys)"
|
||||
|
||||
|
||||
class Generator
|
||||
{
|
||||
typedef enum wrappers {
|
||||
capitalizer,
|
||||
reverser
|
||||
} wrappers_t;
|
||||
|
||||
typedef enum group_types {
|
||||
symbol,
|
||||
literal
|
||||
} group_types_t;
|
||||
|
||||
|
||||
class Group {
|
||||
std::stack<wrappers_t> wrappers;
|
||||
std::vector<std::unique_ptr<Generator>> set;
|
||||
|
||||
public:
|
||||
group_types_t type;
|
||||
|
||||
Group(group_types_t type_);
|
||||
virtual ~Group() { }
|
||||
|
||||
std::unique_ptr<Generator> produce();
|
||||
void split();
|
||||
void wrap(wrappers_t type);
|
||||
void add(std::unique_ptr<Generator>&& g);
|
||||
|
||||
virtual void add(char c);
|
||||
};
|
||||
|
||||
|
||||
class GroupSymbol : public Group {
|
||||
public:
|
||||
GroupSymbol();
|
||||
void add(char c);
|
||||
};
|
||||
|
||||
|
||||
class GroupLiteral : public Group {
|
||||
public:
|
||||
GroupLiteral();
|
||||
};
|
||||
|
||||
protected:
|
||||
std::vector<std::unique_ptr<Generator>> generators;
|
||||
|
||||
public:
|
||||
static const std::unordered_map<std::string, const std::vector<std::string>>& SymbolMap();
|
||||
|
||||
Generator();
|
||||
Generator(const std::string& pattern, bool collapse_triples=true);
|
||||
Generator(std::vector<std::unique_ptr<Generator>>&& generators_);
|
||||
|
||||
virtual ~Generator() = default;
|
||||
|
||||
virtual size_t combinations();
|
||||
virtual size_t min();
|
||||
virtual size_t max();
|
||||
virtual std::string toString();
|
||||
|
||||
void add(std::unique_ptr<Generator>&& g);
|
||||
};
|
||||
|
||||
|
||||
class Random : public Generator
|
||||
{
|
||||
public:
|
||||
Random();
|
||||
Random(std::vector<std::unique_ptr<Generator>>&& generators_);
|
||||
|
||||
size_t combinations();
|
||||
size_t min();
|
||||
size_t max();
|
||||
std::string toString();
|
||||
};
|
||||
|
||||
|
||||
class Sequence : public Generator
|
||||
{
|
||||
public:
|
||||
Sequence();
|
||||
Sequence(std::vector<std::unique_ptr<Generator>>&& generators_);
|
||||
};
|
||||
|
||||
|
||||
class Literal : public Generator
|
||||
{
|
||||
std::string value;
|
||||
|
||||
public:
|
||||
Literal(const std::string& value_);
|
||||
|
||||
size_t combinations();
|
||||
size_t min();
|
||||
size_t max();
|
||||
std::string toString();
|
||||
};
|
||||
|
||||
|
||||
class Reverser : public Generator {
|
||||
public:
|
||||
Reverser(std::unique_ptr<Generator>&& g);
|
||||
|
||||
std::string toString();
|
||||
};
|
||||
|
||||
|
||||
class Capitalizer : public Generator
|
||||
{
|
||||
public:
|
||||
Capitalizer(std::unique_ptr<Generator>&& g);
|
||||
|
||||
std::string toString();
|
||||
};
|
||||
|
||||
|
||||
class Collapser : public Generator
|
||||
{
|
||||
public:
|
||||
Collapser(std::unique_ptr<Generator>&& g);
|
||||
|
||||
std::string toString();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::wstring towstring(const std::string& s);
|
||||
std::string tostring(const std::wstring& s);
|
||||
@ -161,6 +161,7 @@ RULE_BOOL(Character, DismountWater, true, "Dismount horses when entering water")
|
||||
RULE_BOOL(Character, UseNoJunkFishing, false, "Disregards junk items when fishing")
|
||||
RULE_BOOL(Character, SoftDeletes, true, "When characters are deleted in character select, they are only soft deleted")
|
||||
RULE_INT(Character, DefaultGuild, 0, "If not 0, new characters placed into the guild # indicated")
|
||||
RULE_BOOL(Character, ProcessFearedProximity, false, "Processes proximity checks when feared")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mercs)
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9152
|
||||
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9026
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9027
|
||||
#else
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
||||
#endif
|
||||
|
||||
@ -52,6 +52,10 @@ if (-e "eqemu_server_skip_update.txt") {
|
||||
$skip_self_update_check = 1;
|
||||
}
|
||||
|
||||
if (-e "eqemu_server_skip_maps_update.txt") {
|
||||
$skip_self_maps_update_check = 1;
|
||||
}
|
||||
|
||||
#::: Check for script self update
|
||||
check_xml_to_json_conversion() if $ARGV[0] eq "convert_xml";
|
||||
do_self_update_check_routine() if !$skip_self_update_check;
|
||||
@ -460,7 +464,7 @@ sub do_installer_routines {
|
||||
get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1);
|
||||
}
|
||||
|
||||
map_files_fetch_bulk();
|
||||
map_files_fetch_bulk() if !$skip_self_maps_update_check;
|
||||
opcodes_fetch();
|
||||
plugins_fetch();
|
||||
quest_files_fetch();
|
||||
@ -533,7 +537,10 @@ sub check_for_world_bootup_database_update {
|
||||
|
||||
if ($binary_database_version == $local_database_version && $ARGV[0] eq "ran_from_world") {
|
||||
print "[Update] Database up to date...\n";
|
||||
exit;
|
||||
if (trim($db_version[2]) == 0) {
|
||||
print "[Update] Continuing bootup\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#::: We ran world - Database needs to update, lets backup and run updates and continue world bootup
|
||||
@ -1705,26 +1712,22 @@ sub fetch_server_dlls {
|
||||
|
||||
sub fetch_peq_db_full {
|
||||
print "[Install] Downloading latest PEQ Database... Please wait...\n";
|
||||
get_remote_file("http://edit.projecteq.net/weekly/peq_beta.zip", "updates_staged/peq_beta.zip", 1);
|
||||
get_remote_file("http://db.projecteq.net/api/v1/dump/latest", "updates_staged/peq-latest.zip", 1);
|
||||
print "[Install] Downloaded latest PEQ Database... Extracting...\n";
|
||||
unzip('updates_staged/peq_beta.zip', 'updates_staged/peq_db/');
|
||||
my $start_dir = "updates_staged/peq_db";
|
||||
unzip('updates_staged/peq-latest.zip', 'updates_staged/peq_db/');
|
||||
my $start_dir = "updates_staged/peq_db/peq-dump";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$destination_file = $file;
|
||||
$destination_file =~ s/updates_staged\/peq_db\///g;
|
||||
if ($file =~ /peqbeta|player_tables/i) {
|
||||
$destination_file =~ s/updates_staged\/peq_db\/peq-dump\///g;
|
||||
if ($file =~ /create_tables_content|create_tables_login|create_tables_player|create_tables_queryserv|create_tables_state|create_tables_system/i) {
|
||||
print "[Install] DB :: Installing :: " . $destination_file . "\n";
|
||||
get_mysql_result_from_file($file);
|
||||
}
|
||||
}
|
||||
|
||||
#::: PEQ DB baseline version
|
||||
print get_mysql_result("DELETE FROM db_version");
|
||||
print get_mysql_result("INSERT INTO `db_version` (`version`) VALUES (9130);");
|
||||
}
|
||||
|
||||
sub map_files_fetch_bulk {
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
9024|2019_06_27_bots_pet_get_lost.sql|SELECT `bot_command` FROM `bot_command_settings` WHERE `bot_command` LIKE 'petgetlost'|empty|
|
||||
9025|2019_08_26_bots_owner_option_spawn_message.sql|SELECT * FROM db_version WHERE bots_version >= 9025|empty|
|
||||
9026|2019_09_09_bots_owner_options_rework.sql|SHOW COLUMNS FROM `bot_owner_options` LIKE 'option_type'|empty|
|
||||
9027|2020_03_30_bots_view_update.sql|SELECT * FROM db_version WHERE bots_version >= 9027|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
24
utils/sql/git/bots/required/2020_03_30_bots_view_update.sql
Normal file
24
utils/sql/git/bots/required/2020_03_30_bots_view_update.sql
Normal file
@ -0,0 +1,24 @@
|
||||
DROP VIEW IF EXISTS `vw_bot_character_mobs`;
|
||||
|
||||
-- Views
|
||||
CREATE VIEW `vw_bot_character_mobs` AS
|
||||
SELECT
|
||||
_utf8'C' AS mob_type,
|
||||
c.`id`,
|
||||
c.`name`,
|
||||
c.`class`,
|
||||
c.`level`,
|
||||
c.`last_login`,
|
||||
c.`zone_id`,
|
||||
c.`deleted_at`
|
||||
FROM `character_data` AS c
|
||||
UNION ALL
|
||||
SELECT _utf8'B' AS mob_type,
|
||||
b.`bot_id` AS id,
|
||||
b.`name`,
|
||||
b.`class`,
|
||||
b.`level`,
|
||||
b.`last_spawn` AS last_login,
|
||||
b.`zone_id`,
|
||||
NULL AS `deleted_at`
|
||||
FROM `bot_data` AS b;
|
||||
@ -1,7 +1,3 @@
|
||||
ALTER TABLE `aa_actions` ENGINE=InnoDB;
|
||||
ALTER TABLE `aa_effects` ENGINE=InnoDB;
|
||||
ALTER TABLE `aa_required_level_cost` ENGINE=InnoDB;
|
||||
ALTER TABLE `aa_timers` ENGINE=InnoDB;
|
||||
ALTER TABLE `account_flags` ENGINE=InnoDB;
|
||||
ALTER TABLE `account_ip` ENGINE=InnoDB;
|
||||
ALTER TABLE `account` ENGINE=InnoDB;
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "clientlist.h"
|
||||
#include "wguild_mgr.h"
|
||||
#include "sof_char_create_data.h"
|
||||
#include "../common/namegenerator/namegen.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
@ -533,80 +534,14 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
|
||||
// creates up to a 10 char name
|
||||
char vowels[18]="aeiouyaeiouaeioe";
|
||||
char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd";
|
||||
char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr";
|
||||
int rndnum=emu_random.Int(0, 75),n=1;
|
||||
bool dlc=false;
|
||||
bool vwl=false;
|
||||
bool dbl=false;
|
||||
if (rndnum>63)
|
||||
{ // rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel
|
||||
rndnum=(rndnum-61)*2; // name can't start with "ng" "nd" or "rk"
|
||||
rndname[0]=paircons[rndnum];
|
||||
rndname[1]=paircons[rndnum+1];
|
||||
n=2;
|
||||
}
|
||||
else if (rndnum>16)
|
||||
{
|
||||
rndnum-=17;
|
||||
rndname[0]=cons[rndnum];
|
||||
}
|
||||
else
|
||||
{
|
||||
rndname[0]=vowels[rndnum];
|
||||
vwl=true;
|
||||
}
|
||||
int namlen=emu_random.Int(5, 10);
|
||||
for (int i=n;i<namlen;i++)
|
||||
{
|
||||
dlc=false;
|
||||
if (vwl) //last char was a vowel
|
||||
{ // so pick a cons or cons pair
|
||||
rndnum=emu_random.Int(0, 62);
|
||||
if (rndnum>46)
|
||||
{ // pick a cons pair
|
||||
if (i>namlen-3) // last 2 chars in name?
|
||||
{ // name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng"
|
||||
rndnum=emu_random.Int(0, 7)*2;
|
||||
}
|
||||
else
|
||||
{ // pick any from the set
|
||||
rndnum=(rndnum-47)*2;
|
||||
}
|
||||
rndname[i]=paircons[rndnum];
|
||||
rndname[i+1]=paircons[rndnum+1];
|
||||
dlc=true; // flag keeps second letter from being doubled below
|
||||
i+=1;
|
||||
}
|
||||
else
|
||||
{ // select a single cons
|
||||
rndname[i]=cons[rndnum];
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // select a vowel
|
||||
rndname[i]=vowels[emu_random.Int(0, 16)];
|
||||
}
|
||||
vwl=!vwl;
|
||||
if (!dbl && !dlc)
|
||||
{ // one chance at double letters in name
|
||||
if (!emu_random.Int(0, i+9)) // chances decrease towards end of name
|
||||
{
|
||||
rndname[i+1]=rndname[i];
|
||||
dbl=true;
|
||||
i+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app)
|
||||
{
|
||||
NameGen::Generator generator("!Bvss");
|
||||
std::string random_name = generator.toString();
|
||||
|
||||
rndname[0]=toupper(rndname[0]);
|
||||
NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
|
||||
memset(ngs->name,0,64);
|
||||
strcpy(ngs->name,rndname);
|
||||
auto *ngs = (NameGeneration_Struct *) app->pBuffer;
|
||||
memset(ngs->name, 0, 64);
|
||||
strcpy(ngs->name, random_name.c_str());
|
||||
|
||||
QueuePacket(app);
|
||||
return true;
|
||||
|
||||
@ -432,6 +432,7 @@ int main(int argc, char** argv) {
|
||||
RegisterConsoleFunctions(console);
|
||||
}
|
||||
|
||||
zoneserver_list.Init();
|
||||
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
|
||||
server_connection.reset(new EQ::Net::ServertalkServer());
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ ZSList::ZSList()
|
||||
{
|
||||
NextID = 1;
|
||||
CurGroupID = 1;
|
||||
LastAllocatedPort = 0;
|
||||
memset(pLockedZones, 0, sizeof(pLockedZones));
|
||||
|
||||
m_tick.reset(new EQ::Timer(5000, true, std::bind(&ZSList::OnTick, this, std::placeholders::_1)));
|
||||
@ -76,7 +75,12 @@ void ZSList::Remove(const std::string &uuid)
|
||||
auto iter = zone_server_list.begin();
|
||||
while (iter != zone_server_list.end()) {
|
||||
if ((*iter)->GetUUID().compare(uuid) == 0) {
|
||||
auto port = (*iter)->GetCPort();
|
||||
zone_server_list.erase(iter);
|
||||
|
||||
if (port != 0) {
|
||||
m_ports_free.push_back(port);
|
||||
}
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
@ -239,6 +243,14 @@ bool ZSList::SetLockedZone(uint16 iZoneID, bool iLock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZSList::Init()
|
||||
{
|
||||
const WorldConfig* Config = WorldConfig::get();
|
||||
for (uint16 i = Config->ZonePortLow; i <= Config->ZonePortHigh; ++i) {
|
||||
m_ports_free.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZSList::IsZoneLocked(uint16 iZoneID) {
|
||||
for (auto &zone : pLockedZones) {
|
||||
if (zone == iZoneID)
|
||||
@ -577,30 +589,15 @@ void ZSList::RebootZone(const char* ip1, uint16 port, const char* ip2, uint32 sk
|
||||
safe_delete_array(tmp);
|
||||
}
|
||||
|
||||
uint16 ZSList::GetAvailableZonePort()
|
||||
uint16 ZSList::GetAvailableZonePort()
|
||||
{
|
||||
const WorldConfig *Config = WorldConfig::get();
|
||||
int i;
|
||||
uint16 port = 0;
|
||||
|
||||
if (LastAllocatedPort == 0)
|
||||
i = Config->ZonePortLow;
|
||||
else
|
||||
i = LastAllocatedPort + 1;
|
||||
|
||||
while (i != LastAllocatedPort && port == 0) {
|
||||
if (i>Config->ZonePortHigh)
|
||||
i = Config->ZonePortLow;
|
||||
|
||||
if (!FindByPort(i)) {
|
||||
port = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if (m_ports_free.empty()) {
|
||||
return 0;
|
||||
}
|
||||
LastAllocatedPort = port;
|
||||
|
||||
return port;
|
||||
auto first = m_ports_free.front();
|
||||
m_ports_free.pop_front();
|
||||
return first;
|
||||
}
|
||||
|
||||
uint32 ZSList::TriggerBootup(uint32 iZoneID, uint32 iInstanceID) {
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "../common/event/timer.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
class WorldTCPConnection;
|
||||
class ServerPacket;
|
||||
@ -22,6 +23,7 @@ public:
|
||||
ZSList();
|
||||
~ZSList();
|
||||
|
||||
void Init();
|
||||
bool IsZoneLocked(uint16 iZoneID);
|
||||
bool SendPacket(ServerPacket *pack);
|
||||
bool SendPacket(uint32 zoneid, ServerPacket *pack);
|
||||
@ -73,8 +75,7 @@ private:
|
||||
uint32 NextID;
|
||||
uint16 pLockedZones[MaxLockedZones];
|
||||
uint32 CurGroupID;
|
||||
uint16 LastAllocatedPort;
|
||||
|
||||
std::deque<uint16> m_ports_free;
|
||||
std::unique_ptr<EQ::Timer> m_tick;
|
||||
std::unique_ptr<EQ::Timer> m_keepalive;
|
||||
|
||||
|
||||
@ -4018,6 +4018,14 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
||||
//Message(Chat::Red, "You cant cast right now, you arent in control of yourself!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Hack for broken RoF2 which allows casting after a zoned IVU/IVA
|
||||
if (invisible_undead || invisible_animals) {
|
||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
||||
BuffFadeByEffect(SE_InvisVsUndead);
|
||||
BuffFadeByEffect(SE_InvisVsUndead2);
|
||||
BuffFadeByEffect(SE_Invisibility); // Included per JJ for completeness - client handles this one atm
|
||||
}
|
||||
|
||||
CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer;
|
||||
|
||||
|
||||
143
zone/command.cpp
143
zone/command.cpp
@ -196,6 +196,7 @@ int command_init(void)
|
||||
command_add("disarmtrap", "Analog for ldon disarm trap for the newer clients since we still don't have it working.", 80, command_disarmtrap) ||
|
||||
command_add("distance", "- Reports the distance between you and your target.", 80, command_distance) ||
|
||||
command_add("doanim", "[animnum] [type] - Send an EmoteAnim for you or your target", 50, command_doanim) ||
|
||||
command_add("editmassrespawn", "[name-search] [second-value] - Mass (Zone wide) NPC respawn timer editing command", 100, command_editmassrespawn) ||
|
||||
command_add("emote", "['name'/'world'/'zone'] [type] [message] - Send an emote message", 80, command_emote) ||
|
||||
command_add("emotesearch", "Searches NPC Emotes", 80, command_emotesearch) ||
|
||||
command_add("emoteview", "Lists all NPC Emotes", 80, command_emoteview) ||
|
||||
@ -6497,6 +6498,144 @@ void command_doanim(Client *c, const Seperator *sep)
|
||||
c->DoAnim(atoi(sep->arg[1]),atoi(sep->arg[2]));
|
||||
}
|
||||
|
||||
void command_editmassrespawn(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (strcasecmp(sep->arg[1], "usage") == 0) {
|
||||
c->Message(Chat::White, "#editmassrespawn [exact_match: =]npc_type_name new_respawn_seconds (apply)");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string search_npc_type;
|
||||
if (sep->arg[1]) {
|
||||
search_npc_type = sep->arg[1];
|
||||
}
|
||||
|
||||
int change_respawn_seconds = 0;
|
||||
if (sep->arg[2] && sep->IsNumber(2)) {
|
||||
change_respawn_seconds = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
bool change_apply = false;
|
||||
if (sep->arg[3] && strcasecmp(sep->arg[3], "apply") == 0) {
|
||||
change_apply = true;
|
||||
}
|
||||
|
||||
std::string search_encapsulator = "%";
|
||||
if (search_npc_type[0] == '=') {
|
||||
|
||||
search_npc_type = search_npc_type.substr(1);
|
||||
search_encapsulator = "";
|
||||
}
|
||||
|
||||
std::string query = fmt::format(
|
||||
SQL(
|
||||
SELECT npc_types.id, spawn2.spawngroupID, spawn2.id, npc_types.name, spawn2.respawntime
|
||||
FROM spawn2
|
||||
INNER JOIN spawnentry ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||
INNER JOIN npc_types ON spawnentry.npcID = npc_types.id
|
||||
WHERE spawn2.zone LIKE '{}'
|
||||
AND spawn2.version = '{}'
|
||||
AND npc_types.name LIKE '{}{}{}'
|
||||
ORDER BY npc_types.id, spawn2.spawngroupID, spawn2.id
|
||||
),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
search_encapsulator,
|
||||
search_npc_type,
|
||||
search_encapsulator
|
||||
);
|
||||
|
||||
std::string status = "(Searching)";
|
||||
if (change_apply) {
|
||||
status = "(Applying)";
|
||||
}
|
||||
|
||||
int results_count = 0;
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success() && results.RowCount()) {
|
||||
|
||||
results_count = results.RowCount();
|
||||
|
||||
for (auto row : results) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"NPC (npcid:{}) (sgid:{}) (s2id:{}) [{}] Respawn: Current [{}] New [{}] {}",
|
||||
row[0],
|
||||
row[1],
|
||||
row[2],
|
||||
row[3],
|
||||
row[4],
|
||||
change_respawn_seconds,
|
||||
status
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Found (%i) NPC's that match this search...", results_count);
|
||||
|
||||
if (change_respawn_seconds > 0) {
|
||||
|
||||
if (change_apply) {
|
||||
|
||||
results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
SQL(
|
||||
UPDATE spawn2
|
||||
SET respawntime = '{}'
|
||||
WHERE id IN (
|
||||
SELECT spawn2.id
|
||||
FROM spawn2
|
||||
INNER JOIN spawnentry ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||
INNER JOIN npc_types ON spawnentry.npcID = npc_types.id
|
||||
WHERE spawn2.zone LIKE '{}'
|
||||
AND spawn2.version = '{}'
|
||||
AND npc_types.name LIKE '{}{}{}'
|
||||
)
|
||||
),
|
||||
change_respawn_seconds,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
search_encapsulator,
|
||||
search_npc_type,
|
||||
search_encapsulator
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
|
||||
c->Message(Chat::Yellow, "Changes applied to (%i) NPC 'Spawn2' entries", results_count);
|
||||
zone->Repop();
|
||||
}
|
||||
else {
|
||||
|
||||
c->Message(Chat::Yellow, "Found (0) NPC's that match this search...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
std::string saylink = fmt::format(
|
||||
"#editmassrespawn {}{} {} apply",
|
||||
(search_encapsulator.empty() ? "=" : ""),
|
||||
search_npc_type,
|
||||
change_respawn_seconds
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::Yellow, "To apply these changes, click <%s> or type [%s]",
|
||||
EQEmu::SayLinkEngine::GenerateQuestSaylink(saylink, false, "Apply").c_str(),
|
||||
saylink.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
c->Message(Chat::Yellow, "Found (0) NPC's that match this search...");
|
||||
}
|
||||
}
|
||||
|
||||
void command_randomfeatures(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target=c->GetTarget();
|
||||
@ -7807,7 +7946,7 @@ void command_npcemote(Client *c, const Seperator *sep)
|
||||
void command_npceditmass(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (strcasecmp(sep->arg[1], "usage") == 0) {
|
||||
c->Message(Chat::White, "#npceditmass search_column [exact_match: =]search_value change_column change_value");
|
||||
c->Message(Chat::White, "#npceditmass search_column [exact_match: =]search_value change_column change_value (apply)");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7955,7 +8094,7 @@ void command_npceditmass(Client *c, const Seperator *sep)
|
||||
std::string saylink = fmt::format(
|
||||
"#npceditmass {} {}{} {} {} apply",
|
||||
search_column,
|
||||
(exact_match ? '=' : '\0'),
|
||||
(exact_match ? "=" : ""),
|
||||
search_value,
|
||||
change_column,
|
||||
change_value
|
||||
|
||||
@ -91,6 +91,7 @@ void command_disablerecipe(Client *c, const Seperator *sep);
|
||||
void command_disarmtrap(Client *c, const Seperator *sep);
|
||||
void command_distance(Client *c, const Seperator *sep);
|
||||
void command_doanim(Client *c, const Seperator *sep);
|
||||
void command_editmassrespawn(Client* c, const Seperator* sep);
|
||||
void command_emote(Client *c, const Seperator *sep);
|
||||
void command_emotesearch(Client* c, const Seperator *sep);
|
||||
void command_emoteview(Client* c, const Seperator *sep);
|
||||
|
||||
@ -822,6 +822,54 @@ XS(XS__isdisctome) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getracename);
|
||||
XS(XS__getracename) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getracename(uint16 race_id)");
|
||||
|
||||
dXSTARG;
|
||||
uint16 race_id = (int) SvIV(ST(0));
|
||||
std::string race_name = quest_manager.getracename(race_id);
|
||||
|
||||
sv_setpv(TARG, race_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getspellname);
|
||||
XS(XS__getspellname) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getspellname(uint32 spell_id)");
|
||||
|
||||
dXSTARG;
|
||||
uint32 spell_id = (int) SvIV(ST(0));
|
||||
std::string spell_name = quest_manager.getspellname(spell_id);
|
||||
|
||||
sv_setpv(TARG, spell_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getskillname);
|
||||
XS(XS__getskillname) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getskillname(int skill_id)");
|
||||
|
||||
dXSTARG;
|
||||
int skill_id = (int) SvIV(ST(0));
|
||||
std::string skill_name = quest_manager.getskillname(skill_id);
|
||||
|
||||
sv_setpv(TARG, skill_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__safemove);
|
||||
XS(XS__safemove) {
|
||||
dXSARGS;
|
||||
@ -2342,7 +2390,6 @@ XS(XS__updatetaskactivity) {
|
||||
XS(XS__resettaskactivity);
|
||||
XS(XS__resettaskactivity) {
|
||||
dXSARGS;
|
||||
unsigned int task, activity;
|
||||
if (items == 2) {
|
||||
int task_id = (int) SvIV(ST(0));
|
||||
int activity_id = (int) SvIV(ST(1));
|
||||
@ -2613,6 +2660,23 @@ XS(XS__istaskappropriate) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__gettaskname);
|
||||
XS(XS__gettaskname) {
|
||||
dXSARGS;
|
||||
if (items != 1) {
|
||||
Perl_croak(aTHX_ "Usage: quest::gettaskname(uint32 task_id)");
|
||||
}
|
||||
|
||||
dXSTARG;
|
||||
uint32 task_id = (int) SvIV(ST(0));
|
||||
std::string task_name = quest_manager.gettaskname(task_id);
|
||||
|
||||
sv_setpv(TARG, task_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__popup); // prototype to pass -Wmissing-prototypes
|
||||
XS(XS__popup) {
|
||||
dXSARGS;
|
||||
@ -2797,6 +2861,51 @@ XS(XS__collectitems) {
|
||||
XSRETURN_IV(quantity);
|
||||
}
|
||||
|
||||
XS(XS__countitem);
|
||||
XS(XS__countitem) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::countitem(int item_id)");
|
||||
|
||||
uint32 item_id = (int) SvIV(ST(0));
|
||||
|
||||
int quantity = quest_manager.countitem(item_id);
|
||||
|
||||
XSRETURN_IV(quantity);
|
||||
}
|
||||
|
||||
XS(XS__getitemname);
|
||||
XS(XS__getitemname) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getitemname(uint32 item_id)");
|
||||
|
||||
dXSTARG;
|
||||
uint32 item_id = (int) SvIV(ST(0));
|
||||
std::string item_name = quest_manager.getitemname(item_id);
|
||||
|
||||
sv_setpv(TARG, item_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getnpcnamebyid);
|
||||
XS(XS__getnpcnamebyid) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getnpcnamebyid(uint32 npc_id)");
|
||||
|
||||
dXSTARG;
|
||||
uint32 npc_id = (int) SvIV(ST(0));
|
||||
const char *npc_name = quest_manager.getnpcnamebyid(npc_id);
|
||||
|
||||
sv_setpv(TARG, npc_name);
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__UpdateSpawnTimer);
|
||||
XS(XS__UpdateSpawnTimer) {
|
||||
dXSARGS;
|
||||
@ -3063,6 +3172,25 @@ XS(XS__RemoveFromInstanceByCharID) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__CheckInstanceByCharID);
|
||||
XS(XS__CheckInstanceByCharID) {
|
||||
dXSARGS;
|
||||
if (items != 2) {
|
||||
Perl_croak(aTHX_ "Usage: quest::CheckInstanceByCharID(uint16 instance_id, uint32 char_id)");
|
||||
}
|
||||
|
||||
bool RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
uint16 instance_id = (int) SvUV(ST(0));
|
||||
uint32 char_id = (int) SvUV(ST(1));
|
||||
RETVAL = quest_manager.CheckInstanceByCharID(instance_id, char_id);
|
||||
XSprePUSH;
|
||||
PUSHu((IV) RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__RemoveAllFromInstance);
|
||||
XS(XS__RemoveAllFromInstance) {
|
||||
dXSARGS;
|
||||
@ -3151,6 +3279,57 @@ XS(XS__saylink) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getcharnamebyid);
|
||||
XS(XS__getcharnamebyid) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getcharnamebyid(uint32 char_id)");
|
||||
dXSTARG;
|
||||
|
||||
Const_char *RETVAL;
|
||||
uint32 char_id = (int) SvUV(ST(0));
|
||||
|
||||
RETVAL = quest_manager.getcharnamebyid(char_id);
|
||||
|
||||
sv_setpv(TARG, RETVAL);
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
}
|
||||
|
||||
XS(XS__getcharidbyname);
|
||||
XS(XS__getcharidbyname) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getcharidbyname(string name)");
|
||||
dXSTARG;
|
||||
|
||||
uint32 RETVAL;
|
||||
const char *name = (const char *) SvPV_nolen(ST(0));
|
||||
|
||||
RETVAL = quest_manager.getcharidbyname(name);
|
||||
XSprePUSH;
|
||||
PUSHu((UV)RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getcurrencyid);
|
||||
XS(XS__getcurrencyid) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getcurrencyid(uint32 item_id)");
|
||||
dXSTARG;
|
||||
|
||||
int RETVAL;
|
||||
uint32 item_id = (int) SvUV(ST(0));;
|
||||
|
||||
RETVAL = quest_manager.getcurrencyid(item_id);
|
||||
XSprePUSH;
|
||||
PUSHi((IV)RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getguildnamebyid);
|
||||
XS(XS__getguildnamebyid) {
|
||||
dXSARGS;
|
||||
@ -3927,6 +4106,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
|
||||
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
|
||||
newXS(strcpy(buf, "RemoveFromInstanceByCharID"), XS__RemoveFromInstanceByCharID, file);
|
||||
newXS(strcpy(buf, "CheckInstanceByCharID"), XS__CheckInstanceByCharID, file);
|
||||
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
|
||||
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
|
||||
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
|
||||
@ -3951,6 +4131,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "clearspawntimers"), XS__clearspawntimers, file);
|
||||
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
|
||||
newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file);
|
||||
newXS(strcpy(buf, "countitem"), XS__countitem, file);
|
||||
newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file);
|
||||
newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file);
|
||||
newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file);
|
||||
@ -3990,18 +4171,27 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "follow"), XS__follow, file);
|
||||
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
|
||||
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
|
||||
newXS(strcpy(buf, "getcharidbyname"), XS__getcharidbyname, file);
|
||||
newXS(strcpy(buf, "getcurrencyid"), XS__getcurrencyid, file);
|
||||
newXS(strcpy(buf, "getinventoryslotid"), XS__getinventoryslotid, file);
|
||||
newXS(strcpy(buf, "getitemname"), XS__getitemname, file);
|
||||
newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file);
|
||||
newXS(strcpy(buf, "getnpcnamebyid"), XS__getnpcnamebyid, file);
|
||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||
newXS(strcpy(buf, "getcharnamebyid"), XS__getcharnamebyid, file);
|
||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||
newXS(strcpy(buf, "getguildidbycharid"), XS__getguildidbycharid, file);
|
||||
newXS(strcpy(buf, "getgroupidbycharid"), XS__getgroupidbycharid, file);
|
||||
newXS(strcpy(buf, "getraididbycharid"), XS__getraididbycharid, file);
|
||||
newXS(strcpy(buf, "getracename"), XS__getracename, file);
|
||||
newXS(strcpy(buf, "getspellname"), XS__getspellname, file);
|
||||
newXS(strcpy(buf, "getskillname"), XS__getskillname, file);
|
||||
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
||||
newXS(strcpy(buf, "getplayerburiedcorpsecount"), XS__getplayerburiedcorpsecount, file);
|
||||
newXS(strcpy(buf, "getplayercorpsecount"), XS__getplayercorpsecount, file);
|
||||
newXS(strcpy(buf, "getplayercorpsecountbyzoneid"), XS__getplayercorpsecountbyzoneid, file);
|
||||
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
||||
newXS(strcpy(buf, "gettaskname"), XS__gettaskname, file);
|
||||
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
||||
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
||||
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
|
||||
|
||||
@ -393,6 +393,18 @@ bool lua_is_disc_tome(int item_id) {
|
||||
return quest_manager.isdisctome(item_id);
|
||||
}
|
||||
|
||||
std::string lua_get_race_name(uint32 race_id) {
|
||||
return quest_manager.getracename(race_id);
|
||||
}
|
||||
|
||||
std::string lua_get_spell_name(uint32 spell_id) {
|
||||
return quest_manager.getspellname(spell_id);
|
||||
}
|
||||
|
||||
std::string lua_get_skill_name(int skill_id) {
|
||||
return quest_manager.getskillname(skill_id);
|
||||
}
|
||||
|
||||
void lua_safe_move() {
|
||||
quest_manager.safemove();
|
||||
}
|
||||
@ -729,6 +741,10 @@ bool lua_is_task_appropriate(int task) {
|
||||
return quest_manager.istaskappropriate(task);
|
||||
}
|
||||
|
||||
std::string lua_get_task_name(uint32 task_id) {
|
||||
return quest_manager.gettaskname(task_id);
|
||||
}
|
||||
|
||||
void lua_popup(const char *title, const char *text, uint32 id, uint32 buttons, uint32 duration) {
|
||||
quest_manager.popup(title, text, id, buttons, duration);
|
||||
}
|
||||
@ -781,6 +797,10 @@ int lua_collect_items(uint32 item_id, bool remove) {
|
||||
return quest_manager.collectitems(item_id, remove);
|
||||
}
|
||||
|
||||
int lua_count_item(uint32 item_id) {
|
||||
return quest_manager.countitem(item_id);
|
||||
}
|
||||
|
||||
void lua_update_spawn_timer(uint32 id, uint32 new_time) {
|
||||
quest_manager.UpdateSpawnTimer(id, new_time);
|
||||
}
|
||||
@ -803,6 +823,10 @@ std::string lua_item_link(int item_id) {
|
||||
return quest_manager.varlink(text, item_id);
|
||||
}
|
||||
|
||||
std::string lua_get_item_name(uint32 item_id) {
|
||||
return quest_manager.getitemname(item_id);
|
||||
}
|
||||
|
||||
std::string lua_say_link(const char *phrase, bool silent, const char *link_name) {
|
||||
char text[256] = { 0 };
|
||||
strncpy(text, phrase, 255);
|
||||
@ -854,6 +878,18 @@ bool lua_delete_data(std::string bucket_key) {
|
||||
return DataBucket::DeleteData(bucket_key);
|
||||
}
|
||||
|
||||
const char *lua_get_char_name_by_id(uint32 char_id) {
|
||||
return database.GetCharNameByID(char_id);
|
||||
}
|
||||
|
||||
uint32 lua_get_char_id_by_name(const char* name) {
|
||||
return quest_manager.getcharidbyname(name);
|
||||
}
|
||||
|
||||
int lua_get_currency_id(uint32 item_id) {
|
||||
return quest_manager.getcurrencyid(item_id);
|
||||
}
|
||||
|
||||
const char *lua_get_guild_name_by_id(uint32 guild_id) {
|
||||
return quest_manager.getguildnamebyid(guild_id);
|
||||
}
|
||||
@ -866,6 +902,10 @@ int lua_get_group_id_by_char_id(uint32 char_id) {
|
||||
return database.GetGroupIDByCharID(char_id);
|
||||
}
|
||||
|
||||
const char *lua_get_npc_name_by_id(uint32 npc_id) {
|
||||
return quest_manager.getnpcnamebyid(npc_id);
|
||||
}
|
||||
|
||||
int lua_get_raid_id_by_char_id(uint32 char_id) {
|
||||
return database.GetRaidIDByCharID(char_id);
|
||||
}
|
||||
@ -922,6 +962,10 @@ void lua_remove_from_instance_by_char_id(uint32 instance_id, uint32 char_id) {
|
||||
quest_manager.RemoveFromInstanceByCharID(instance_id, char_id);
|
||||
}
|
||||
|
||||
bool lua_check_instance_by_char_id(uint32 instance_id, uint32 char_id) {
|
||||
return quest_manager.CheckInstanceByCharID(instance_id, char_id);
|
||||
}
|
||||
|
||||
void lua_remove_all_from_instance(uint32 instance_id) {
|
||||
quest_manager.RemoveAllFromInstance(instance_id);
|
||||
}
|
||||
@ -1644,6 +1688,9 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("depop_zone", &lua_depop_zone),
|
||||
luabind::def("repop_zone", &lua_repop_zone),
|
||||
luabind::def("is_disc_tome", &lua_is_disc_tome),
|
||||
luabind::def("get_race_name", (std::string(*)(uint16))&lua_get_race_name),
|
||||
luabind::def("get_spell_name", (std::string(*)(uint32))&lua_get_spell_name),
|
||||
luabind::def("get_skill_name", (std::string(*)(int))&lua_get_skill_name),
|
||||
luabind::def("safe_move", &lua_safe_move),
|
||||
luabind::def("rain", &lua_rain),
|
||||
luabind::def("snow", &lua_snow),
|
||||
@ -1711,6 +1758,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("active_tasks_in_set", &lua_active_tasks_in_set),
|
||||
luabind::def("completed_tasks_in_set", &lua_completed_tasks_in_set),
|
||||
luabind::def("is_task_appropriate", &lua_is_task_appropriate),
|
||||
luabind::def("get_task_name", (std::string(*)(uint32))&lua_get_task_name),
|
||||
luabind::def("popup", &lua_popup),
|
||||
luabind::def("clear_spawn_timers", &lua_clear_spawn_timers),
|
||||
luabind::def("zone_emote", &lua_zone_emote),
|
||||
@ -1724,11 +1772,13 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("create_door", &lua_create_door),
|
||||
luabind::def("modify_npc_stat", &lua_modify_npc_stat),
|
||||
luabind::def("collect_items", &lua_collect_items),
|
||||
luabind::def("count_item", &lua_count_item),
|
||||
luabind::def("update_spawn_timer", &lua_update_spawn_timer),
|
||||
luabind::def("merchant_set_item", (void(*)(uint32,uint32))&lua_merchant_set_item),
|
||||
luabind::def("merchant_set_item", (void(*)(uint32,uint32,uint32))&lua_merchant_set_item),
|
||||
luabind::def("merchant_count_item", &lua_merchant_count_item),
|
||||
luabind::def("item_link", &lua_item_link),
|
||||
luabind::def("get_item_name", (std::string(*)(uint32))&lua_get_item_name),
|
||||
luabind::def("say_link", (std::string(*)(const char*,bool,const char*))&lua_say_link),
|
||||
luabind::def("say_link", (std::string(*)(const char*,bool))&lua_say_link),
|
||||
luabind::def("say_link", (std::string(*)(const char*))&lua_say_link),
|
||||
@ -1739,9 +1789,13 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("set_data", (void(*)(std::string, std::string))&lua_set_data),
|
||||
luabind::def("set_data", (void(*)(std::string, std::string, std::string))&lua_set_data),
|
||||
luabind::def("delete_data", (bool(*)(std::string))&lua_delete_data),
|
||||
luabind::def("get_char_name_by_id", &lua_get_char_name_by_id),
|
||||
luabind::def("get_char_id_by_name", (uint32(*)(const char*))&lua_get_char_id_by_name),
|
||||
luabind::def("get_currency_id", &lua_get_currency_id),
|
||||
luabind::def("get_guild_name_by_id", &lua_get_guild_name_by_id),
|
||||
luabind::def("get_guild_id_by_char_id", &lua_get_guild_id_by_char_id),
|
||||
luabind::def("get_group_id_by_char_id", &lua_get_group_id_by_char_id),
|
||||
luabind::def("get_npc_name_by_id", &lua_get_npc_name_by_id),
|
||||
luabind::def("get_raid_id_by_char_id", &lua_get_raid_id_by_char_id),
|
||||
luabind::def("create_instance", &lua_create_instance),
|
||||
luabind::def("destroy_instance", &lua_destroy_instance),
|
||||
@ -1757,6 +1811,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("assign_raid_to_instance", &lua_assign_raid_to_instance),
|
||||
luabind::def("remove_from_instance", &lua_remove_from_instance),
|
||||
luabind::def("remove_from_instance_by_char_id", &lua_remove_from_instance_by_char_id),
|
||||
luabind::def("check_instance_by_char_id", (bool(*)(uint16, uint32))&lua_check_instance_by_char_id),
|
||||
luabind::def("remove_all_from_instance", &lua_remove_all_from_instance),
|
||||
luabind::def("flag_instance_by_group_leader", &lua_flag_instance_by_group_leader),
|
||||
luabind::def("flag_instance_by_raid_leader", &lua_flag_instance_by_raid_leader),
|
||||
|
||||
@ -67,6 +67,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/event/timer.h"
|
||||
#include "../common/net/eqstream.h"
|
||||
#include "../common/net/servertalk_server.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -93,9 +94,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#endif
|
||||
|
||||
#include "../common/content/world_content_service.h"
|
||||
|
||||
|
||||
volatile bool RunLoops = true;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
@ -609,19 +607,19 @@ int main(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
Zone::Shutdown(true);
|
||||
LogInfo("Shutting down...");
|
||||
LogSys.CloseFileLogs();
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
}
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
#ifdef _WINDOWS
|
||||
LogInfo("Recieved signal: [{}]", sig_num);
|
||||
#endif
|
||||
RunLoops = false;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
Zone::Shutdown(true);
|
||||
RunLoops = false;
|
||||
LogInfo("Shutting down...");
|
||||
LogSys.CloseFileLogs();
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
/* Update Window Title with relevant information */
|
||||
|
||||
@ -747,6 +747,13 @@ void Client::AI_Process()
|
||||
RunTo(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z);
|
||||
}
|
||||
}
|
||||
if (RuleB(Character, ProcessFearedProximity) && proximity_timer.Check()) {
|
||||
entity_list.ProcessMove(this, glm::vec3(GetX(), GetY(), GetZ()));
|
||||
if (RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem, EnableTaskProximity))
|
||||
ProcessTaskProximities(GetX(), GetY(), GetZ());
|
||||
|
||||
m_Proximity = glm::vec3(GetX(), GetY(), GetZ());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -962,7 +962,7 @@ void NPC::Depop(bool StartSpawnTimer) {
|
||||
}
|
||||
|
||||
bool NPC::DatabaseCastAccepted(int spell_id) {
|
||||
for (int i=0; i < 12; i++) {
|
||||
for (int i=0; i < EFFECT_COUNT; i++) {
|
||||
switch(spells[spell_id].effectid[i]) {
|
||||
case SE_Stamina: {
|
||||
if(IsEngaged() && GetHPRatio() < 100)
|
||||
|
||||
@ -906,6 +906,31 @@ bool QuestManager::isdisctome(int item_id) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
std::string QuestManager::getracename(uint16 race_id) {
|
||||
return GetRaceIDName(race_id);
|
||||
}
|
||||
|
||||
std::string QuestManager::getspellname(uint32 spell_id) {
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
return "INVALID SPELL ID IN GETSPELLNAME";
|
||||
}
|
||||
|
||||
std::string spell_name = GetSpellName(spell_id);
|
||||
return spell_name;
|
||||
}
|
||||
|
||||
std::string QuestManager::getskillname(int skill_id) {
|
||||
if (skill_id >= 0 && skill_id < EQEmu::skills::SkillCount) {
|
||||
std::map<EQEmu::skills::SkillType, std::string> Skills = EQEmu::skills::GetSkillTypeMap();
|
||||
for (auto skills_iter : Skills) {
|
||||
if (skill_id == skills_iter.first) {
|
||||
return skills_iter.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void QuestManager::safemove() {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (initiator && initiator->IsClient())
|
||||
@ -2432,6 +2457,16 @@ bool QuestManager::istaskappropriate(int task) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string QuestManager::gettaskname(uint32 task_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
if (RuleB(TaskSystem, EnableTaskSystem)) {
|
||||
return taskmanager->GetTaskName(task_id);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void QuestManager::clearspawntimers() {
|
||||
if(!zone)
|
||||
return;
|
||||
@ -2580,6 +2615,32 @@ int QuestManager::collectitems(uint32 item_id, bool remove)
|
||||
return quantity;
|
||||
}
|
||||
|
||||
int QuestManager::countitem(uint32 item_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
int quantity = 0;
|
||||
EQEmu::ItemInstance *item = nullptr;
|
||||
static const int16 slots[][2] = {
|
||||
{ EQEmu::invslot::POSSESSIONS_BEGIN, EQEmu::invslot::POSSESSIONS_END },
|
||||
{ EQEmu::invbag::GENERAL_BAGS_BEGIN, EQEmu::invbag::GENERAL_BAGS_END },
|
||||
{ EQEmu::invbag::CURSOR_BAG_BEGIN, EQEmu::invbag::CURSOR_BAG_END},
|
||||
{ EQEmu::invslot::BANK_BEGIN, EQEmu::invslot::BANK_END },
|
||||
{ EQEmu::invbag::BANK_BAGS_BEGIN, EQEmu::invbag::BANK_BAGS_END },
|
||||
{ EQEmu::invslot::SHARED_BANK_BEGIN, EQEmu::invslot::SHARED_BANK_END },
|
||||
{ EQEmu::invbag::SHARED_BANK_BAGS_BEGIN, EQEmu::invbag::SHARED_BANK_BAGS_END },
|
||||
};
|
||||
const size_t size = sizeof(slots) / sizeof(slots[0]);
|
||||
for (int slot_index = 0; slot_index < size; ++slot_index) {
|
||||
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||
item = initiator->GetInv().GetItem(slot_id);
|
||||
if (item && item->GetID() == item_id) {
|
||||
quantity += item->IsStackable() ? item->GetCharges() : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return quantity;
|
||||
}
|
||||
|
||||
void QuestManager::UpdateSpawnTimer(uint32 id, uint32 newTime)
|
||||
{
|
||||
bool found = false;
|
||||
@ -2670,6 +2731,23 @@ const char* QuestManager::varlink(char* perltext, int item_id) {
|
||||
return perltext;
|
||||
}
|
||||
|
||||
std::string QuestManager::getitemname(uint32 item_id) {
|
||||
const EQEmu::ItemData* item_data = database.GetItem(item_id);
|
||||
if (!item_data) {
|
||||
return "INVALID ITEM ID IN GETITEMNAME";
|
||||
}
|
||||
|
||||
std::string item_name = item_data->Name;
|
||||
return item_name;
|
||||
}
|
||||
|
||||
const char *QuestManager::getnpcnamebyid(uint32 npc_id) {
|
||||
if (npc_id > 0) {
|
||||
return database.GetNPCNameByID(npc_id);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
uint16 QuestManager::CreateInstance(const char *zone, int16 version, uint32 duration)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
@ -2811,6 +2889,10 @@ void QuestManager::RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id
|
||||
database.RemoveClientFromInstance(instance_id, char_id);
|
||||
}
|
||||
|
||||
bool QuestManager::CheckInstanceByCharID(uint16 instance_id, uint32 char_id) {
|
||||
return database.CharacterInInstanceGroup(instance_id, char_id);
|
||||
}
|
||||
|
||||
void QuestManager::RemoveAllFromInstance(uint16 instance_id)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
@ -2869,6 +2951,28 @@ std::string QuestManager::saylink(char *saylink_text, bool silent, const char *l
|
||||
return EQEmu::SayLinkEngine::GenerateQuestSaylink(saylink_text, silent, link_name);
|
||||
}
|
||||
|
||||
const char* QuestManager::getcharnamebyid(uint32 char_id) {
|
||||
if (char_id > 0) {
|
||||
return database.GetCharNameByID(char_id);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
uint32 QuestManager::getcharidbyname(const char* name) {
|
||||
return database.GetCharacterID(name);
|
||||
}
|
||||
|
||||
int QuestManager::getcurrencyid(uint32 item_id) {
|
||||
auto iter = zone->AlternateCurrencies.begin();
|
||||
while (iter != zone->AlternateCurrencies.end()) {
|
||||
if (item_id == (*iter).item_id) {
|
||||
return (*iter).id;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* QuestManager::getguildnamebyid(int guild_id) {
|
||||
if (guild_id > 0)
|
||||
return guild_mgr.GetGuildName(guild_id);
|
||||
|
||||
@ -107,6 +107,9 @@ public:
|
||||
void level(int newlevel);
|
||||
void traindisc(int discipline_tome_item_id);
|
||||
bool isdisctome(int item_id);
|
||||
std::string getracename(uint16 race_id);
|
||||
std::string getspellname(uint32 spell_id);
|
||||
std::string getskillname(int skill_id);
|
||||
void safemove();
|
||||
void rain(int weather);
|
||||
void snow(int weather);
|
||||
@ -213,12 +216,15 @@ public:
|
||||
int activetasksinset(int taskset);
|
||||
int completedtasksinset(int taskset);
|
||||
bool istaskappropriate(int task);
|
||||
std::string gettaskname(uint32 task_id);
|
||||
void clearspawntimers();
|
||||
void ze(int type, const char *str);
|
||||
void we(int type, const char *str);
|
||||
int getlevel(uint8 type);
|
||||
int collectitems(uint32 item_id, bool remove);
|
||||
int collectitems_processSlot(int16 slot_id, uint32 item_id, bool remove);
|
||||
int countitem(uint32 item_id);
|
||||
std::string getitemname(uint32 item_id);
|
||||
void enabletitle(int titleset);
|
||||
bool checktitle(int titlecheck);
|
||||
void removetitle(int titlecheck);
|
||||
@ -242,6 +248,7 @@ public:
|
||||
void AssignRaidToInstance(uint16 instance_id);
|
||||
void RemoveFromInstance(uint16 instance_id);
|
||||
void RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 char_id);
|
||||
//void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||
//void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||
void RemoveAllFromInstance(uint16 instance_id);
|
||||
@ -250,9 +257,13 @@ public:
|
||||
void FlagInstanceByRaidLeader(uint32 zone, int16 version);
|
||||
const char* varlink(char* perltext, int item_id);
|
||||
std::string saylink(char *saylink_text, bool silent, const char *link_name);
|
||||
const char* getcharnamebyid(uint32 char_id);
|
||||
uint32 getcharidbyname(const char* name);
|
||||
int getcurrencyid(uint32 item_id);
|
||||
const char* getguildnamebyid(int guild_id);
|
||||
int getguildidbycharid(uint32 char_id);
|
||||
int getgroupidbycharid(uint32 char_id);
|
||||
const char* getnpcnamebyid(uint32 npc_id);
|
||||
int getraididbycharid(uint32 char_id);
|
||||
void SetRunning(bool val);
|
||||
bool IsRunning();
|
||||
|
||||
@ -3426,6 +3426,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
bool isproc, int level_override)
|
||||
{
|
||||
|
||||
bool is_damage_or_lifetap_spell = IsDamageSpell(spell_id) || IsLifetapSpell(spell_id);
|
||||
|
||||
// well we can't cast a spell on target without a target
|
||||
if(!spelltar)
|
||||
{
|
||||
@ -3967,9 +3969,6 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
// send to people in the area, ignoring caster and target
|
||||
//live dosent send this to anybody but the caster
|
||||
//entity_list.QueueCloseClients(spelltar, action_packet, true, 200, this, true, spelltar->IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS);
|
||||
|
||||
// TEMPORARY - this is the message for the spell.
|
||||
// double message on effects that use ChangeHP - working on this
|
||||
message_packet = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
||||
CombatDamage_Struct *cd = (CombatDamage_Struct *)message_packet->pBuffer;
|
||||
cd->target = action->target;
|
||||
@ -3980,7 +3979,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
cd->hit_heading = action->hit_heading;
|
||||
cd->hit_pitch = action->hit_pitch;
|
||||
cd->damage = 0;
|
||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity)){
|
||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity) && !is_damage_or_lifetap_spell){
|
||||
entity_list.QueueCloseClients(
|
||||
spelltar, /* Sender */
|
||||
message_packet, /* Packet */
|
||||
@ -3990,6 +3989,19 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
true, /* Packet ACK */
|
||||
(spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells) /* Message Filter Type: (8 or 9) */
|
||||
);
|
||||
} else if (is_damage_or_lifetap_spell &&
|
||||
(IsClient() ||
|
||||
(HasOwner() &&
|
||||
GetOwner()->IsClient()
|
||||
)
|
||||
)
|
||||
) {
|
||||
(HasOwner() ? GetOwner() : this)->CastToClient()->QueuePacket(
|
||||
message_packet,
|
||||
true,
|
||||
Mob::CLIENT_CONNECTINGALL,
|
||||
(spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells)
|
||||
);
|
||||
}
|
||||
safe_delete(action_packet);
|
||||
safe_delete(message_packet);
|
||||
|
||||
@ -955,6 +955,17 @@ bool TaskManager::AppropriateLevel(int TaskID, int PlayerLevel) {
|
||||
|
||||
}
|
||||
|
||||
std::string TaskManager::GetTaskName(uint32 task_id)
|
||||
{
|
||||
if (task_id > 0 && task_id < MAXTASKS) {
|
||||
if (Tasks[task_id] != nullptr) {
|
||||
return Tasks[task_id]->Title;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int TaskManager::GetTaskMinLevel(int TaskID)
|
||||
{
|
||||
if (Tasks[TaskID]->MinLevel)
|
||||
|
||||
@ -299,6 +299,7 @@ public:
|
||||
bool AppropriateLevel(int TaskID, int PlayerLevel);
|
||||
int GetTaskMinLevel(int TaskID);
|
||||
int GetTaskMaxLevel(int TaskID);
|
||||
std::string GetTaskName(uint32 task_id);
|
||||
void TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID);
|
||||
void TaskQuestSetSelector(Client *c, ClientTaskState *state, Mob *mob, int count, int *tasks); // task list provided by QuestManager (perl/lua)
|
||||
void SendActiveTasksToClient(Client *c, bool TaskComplete=false);
|
||||
|
||||
@ -57,7 +57,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern void CatchSignal(int);
|
||||
extern void Shutdown();
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern uint32 numclients;
|
||||
@ -192,8 +192,15 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
if (pack->size != sizeof(ServerConnectInfo))
|
||||
break;
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*)pack->pBuffer;
|
||||
LogInfo("World assigned Port: [{}] for this zone", sci->port);
|
||||
ZoneConfig::SetZonePort(sci->port);
|
||||
|
||||
if (sci->port == 0) {
|
||||
LogCritical("World did not have a port to assign from this server, the port range was not large enough.");
|
||||
Shutdown();
|
||||
}
|
||||
else {
|
||||
LogInfo("World assigned Port: [{}] for this zone", sci->port);
|
||||
ZoneConfig::SetZonePort(sci->port);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_ChannelMessage: {
|
||||
@ -482,7 +489,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
case ServerOP_ShutdownAll: {
|
||||
entity_list.Save();
|
||||
CatchSignal(2);
|
||||
Shutdown();
|
||||
break;
|
||||
}
|
||||
case ServerOP_ZoneShutdown: {
|
||||
|
||||
@ -3708,7 +3708,7 @@ void ZoneDatabase::LoadBuffs(Client *client)
|
||||
if (!IsValidSpell(buffs[index].spellid))
|
||||
continue;
|
||||
|
||||
for (int effectIndex = 0; effectIndex < 12; ++effectIndex) {
|
||||
for (int effectIndex = 0; effectIndex < EFFECT_COUNT; ++effectIndex) {
|
||||
|
||||
if (spells[buffs[index].spellid].effectid[effectIndex] == SE_Charm) {
|
||||
buffs[index].spellid = SPELL_UNKNOWN;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user