mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 09:31:30 +00:00
Merge branch 'master' into eqstream
This commit is contained in:
commit
48412087e8
@ -1,5 +1,8 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 21/01/2016 ==
|
||||
Uleat: Disabled RoF+ clients from augmentation items not in their possessions slots (0-29, 9999, 251-330) to abate an exploit in the current code
|
||||
|
||||
== 10/17/2016 ==
|
||||
Uleat: Moved namespace ItemField from item_instance.h to shareddb.cpp - the only place it is used
|
||||
Uleat: Separated class Inventory from item_instance files into inventory_profile files
|
||||
|
||||
@ -1700,6 +1700,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].pvpresistcalc=atoi(row[178]);
|
||||
sp[tempid].pvpresistcap=atoi(row[179]);
|
||||
sp[tempid].spell_category=atoi(row[180]);
|
||||
sp[tempid].pcnpc_only_flag=atoi(row[183]);
|
||||
sp[tempid].cast_not_standing = atoi(row[184]) != 0;
|
||||
sp[tempid].can_mgb=atoi(row[185]);
|
||||
sp[tempid].dispel_flag = atoi(row[186]);
|
||||
|
||||
@ -735,7 +735,7 @@ struct SPDat_Spell_Struct
|
||||
/* 180 */ int spell_category; // -- GLOBAL_GROUP
|
||||
/* 181 */ //int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION
|
||||
/* 182 */ //int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP
|
||||
/* 183 */ //int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
|
||||
/* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
|
||||
/* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING
|
||||
/* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB
|
||||
/* 186 */ int dispel_flag; // -- NO_DISPELL
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9100
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9101
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008
|
||||
#else
|
||||
|
||||
@ -43,8 +43,12 @@ if($Config{osname}=~/Win|MS/i){
|
||||
$has_internet_connection = check_internet_connection();
|
||||
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
|
||||
|
||||
if(-e "eqemu_server_skip_update.txt"){
|
||||
$skip_self_update_check = 1;
|
||||
}
|
||||
|
||||
#::: Check for script self update
|
||||
do_self_update_check_routine();
|
||||
do_self_update_check_routine() if !$skip_self_update_check;
|
||||
get_perl_version();
|
||||
read_eqemu_config_xml();
|
||||
get_mysql_path();
|
||||
@ -558,6 +562,7 @@ sub do_self_update_check_routine {
|
||||
}
|
||||
|
||||
unlink("updates_staged/eqemu_server.pl");
|
||||
unlink("updates_staged");
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,13 +725,14 @@ sub show_menu_prompt {
|
||||
print " [utility_scripts] Download utility scripts to run and operate the EQEmu Server\n";
|
||||
if($OS eq "Windows"){
|
||||
print ">>> Windows\n";
|
||||
print " [windows_server_download] Updates server code from latest stable\n";
|
||||
print " [windows_server_download_bots] Updates server code (bots enabled) from latest\n";
|
||||
print " [windows_server_download] Updates server via latest 'stable' code\n";
|
||||
print " [windows_server_latest] Updates server via latest commit 'unstable'\n";
|
||||
print " [windows_server_download_bots] Updates server (bots) from latest 'stable'\n";
|
||||
print " [fetch_dlls] Grabs dll's needed to run windows binaries\n";
|
||||
print " [setup_loginserver] Sets up loginserver for Windows\n";
|
||||
}
|
||||
print " \n> main - go back to main menu\n";
|
||||
print "Enter a command #> ";
|
||||
print "Enter a command #> ";
|
||||
$last_menu = trim($input);
|
||||
}
|
||||
elsif($input eq "backup_database"){ database_dump(); $dc = 1; }
|
||||
@ -741,6 +747,7 @@ sub show_menu_prompt {
|
||||
elsif($input eq "quests"){ quest_files_fetch(); $dc = 1; }
|
||||
elsif($input eq "lua_modules"){ lua_modules_fetch(); $dc = 1; }
|
||||
elsif($input eq "windows_server_download"){ fetch_latest_windows_binaries(); $dc = 1; }
|
||||
elsif($input eq "windows_server_latest"){ fetch_latest_windows_appveyor(); $dc = 1; }
|
||||
elsif($input eq "windows_server_download_bots"){ fetch_latest_windows_binaries_bots(); $dc = 1; }
|
||||
elsif($input eq "fetch_dlls"){ fetch_server_dlls(); $dc = 1; }
|
||||
elsif($input eq "utility_scripts"){ fetch_utility_scripts(); $dc = 1; }
|
||||
@ -1205,6 +1212,31 @@ sub copy_file {
|
||||
copy $l_source_file, $l_destination_file;
|
||||
}
|
||||
|
||||
sub fetch_latest_windows_appveyor {
|
||||
print "[Update] Fetching Latest Windows Binaries (unstable) from Appveyor... \n";
|
||||
get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86_pdb.zip", "updates_staged/master_windows_build_pdb.zip", 1);
|
||||
get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86.zip", "updates_staged/master_windows_build.zip", 1);
|
||||
print "[Update] Fetched Latest Windows Binaries (unstable) from Appveyor... \n";
|
||||
print "[Update] Extracting... --- \n";
|
||||
unzip('updates_staged/master_windows_build.zip', 'updates_staged/binaries/');
|
||||
unzip('updates_staged/master_windows_build_pdb.zip', 'updates_staged/binaries/');
|
||||
my @files;
|
||||
my $start_dir = "updates_staged/binaries";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$destination_file = $file;
|
||||
$destination_file =~s/updates_staged\/binaries\///g;
|
||||
print "[Update] Installing :: " . $destination_file . "\n";
|
||||
copy_file($file, $destination_file);
|
||||
}
|
||||
print "[Update] Done\n";
|
||||
|
||||
rmtree('updates_staged');
|
||||
}
|
||||
|
||||
sub fetch_latest_windows_binaries {
|
||||
print "[Update] Fetching Latest Windows Binaries... \n";
|
||||
get_remote_file($install_repository_request_url . "master_windows_build.zip", "updates_staged/master_windows_build.zip", 1);
|
||||
|
||||
@ -354,6 +354,7 @@
|
||||
9098|2016_08_26_object_size_tilt.sql|SHOW COLUMNS FROM `object` LIKE 'size'|empty|
|
||||
9099|2016_08_27_ip_exemptions.sql|SHOW TABLES LIKE 'ip_exemptions'|empty|
|
||||
9100|2016_08_27_object_display_name.sql|SHOW COLUMNS FROM `object` LIKE 'display_name'|empty|
|
||||
9101|2016_12_01_pcnpc_only.sql|SHOW COLUMNS FROM `spells_new` LIKE 'pcnpc_only_flag'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
2
utils/sql/git/required/2016_12_01_pcnpc_only.sql
Normal file
2
utils/sql/git/required/2016_12_01_pcnpc_only.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `spells_new` CHANGE `field183` `pcnpc_only_flag` INT(11) DEFAULT 0;
|
||||
ALTER TABLE `spells_new` CHANGE `field184` `cast_not_standing` INT(11) DEFAULT 0;
|
||||
@ -424,6 +424,7 @@ Client::~Client() {
|
||||
|
||||
void Client::SendZoneInPackets()
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Spawn Appearance Packet
|
||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
|
||||
@ -493,6 +493,7 @@ int Client::HandlePacket(const EQApplicationPacket *app)
|
||||
// Finish client connecting state
|
||||
void Client::CompleteConnect()
|
||||
{
|
||||
|
||||
UpdateWho();
|
||||
client_state = CLIENT_CONNECTED;
|
||||
SendAllPackets();
|
||||
@ -502,27 +503,6 @@ void Client::CompleteConnect()
|
||||
SetDuelTarget(0);
|
||||
SetDueling(false);
|
||||
|
||||
database.LoadPetInfo(this);
|
||||
/*
|
||||
This was moved before the spawn packets are sent
|
||||
in hopes that it adds more consistency...
|
||||
Remake pet
|
||||
*/
|
||||
if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
|
||||
MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
|
||||
if (GetPet() && GetPet()->IsNPC()) {
|
||||
NPC *pet = GetPet()->CastToNPC();
|
||||
pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
|
||||
pet->CalcBonuses();
|
||||
pet->SetHP(m_petinfo.HP);
|
||||
pet->SetMana(m_petinfo.Mana);
|
||||
}
|
||||
m_petinfo.SpellID = 0;
|
||||
}
|
||||
/* Moved here so it's after where we load the pet data. */
|
||||
if (!GetAA(aaPersistentMinion))
|
||||
memset(&m_suspendedminion, 0, sizeof(PetInfo));
|
||||
|
||||
EnteringMessages(this);
|
||||
LoadZoneFlags();
|
||||
|
||||
@ -1480,7 +1460,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
|
||||
database.LoadBuffs(this);
|
||||
uint32 max_slots = GetMaxBuffSlots();
|
||||
for (int i = 0; i < max_slots; i++) {
|
||||
for (int i = 0; i < BUFF_COUNT; i++) {
|
||||
if (buffs[i].spellid != SPELL_UNKNOWN) {
|
||||
m_pp.buffs[i].spellid = buffs[i].spellid;
|
||||
m_pp.buffs[i].bard_modifier = buffs[i].instrument_mod;
|
||||
@ -1649,6 +1629,23 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (m_pp.RestTimer)
|
||||
rest_timer.Start(m_pp.RestTimer * 1000);
|
||||
|
||||
/* Load Pet */
|
||||
database.LoadPetInfo(this);
|
||||
if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
|
||||
MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
|
||||
if (GetPet() && GetPet()->IsNPC()) {
|
||||
NPC *pet = GetPet()->CastToNPC();
|
||||
pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
|
||||
pet->CalcBonuses();
|
||||
pet->SetHP(m_petinfo.HP);
|
||||
pet->SetMana(m_petinfo.Mana);
|
||||
}
|
||||
m_petinfo.SpellID = 0;
|
||||
}
|
||||
/* Moved here so it's after where we load the pet data. */
|
||||
if (!GetAA(aaPersistentMinion))
|
||||
memset(&m_suspendedminion, 0, sizeof(PetInfo));
|
||||
|
||||
/* Server Zone Entry Packet */
|
||||
outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
|
||||
ServerZoneEntry_Struct* sze = (ServerZoneEntry_Struct*)outapp->pBuffer;
|
||||
@ -2933,6 +2930,19 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
bool deleteItems = false;
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
|
||||
{
|
||||
if ((in_augment->container_slot < 0 || in_augment->container_slot >= EQEmu::legacy::SLOT_CURSOR) &&
|
||||
in_augment->container_slot != EQEmu::legacy::SLOT_POWER_SOURCE &&
|
||||
(in_augment->container_slot < EQEmu::legacy::SLOT_PERSONAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::legacy::SLOT_PERSONAL_BAGS_END))
|
||||
{
|
||||
Message(13, "The server does not allow augmentation actions from this slot.");
|
||||
auto cursor_item = m_inv[EQEmu::legacy::SLOT_CURSOR];
|
||||
auto augmented_item = m_inv[in_augment->container_slot];
|
||||
SendItemPacket(EQEmu::legacy::SLOT_CURSOR, cursor_item, ItemPacketCharInventory);
|
||||
// this may crash clients on certain slots
|
||||
SendItemPacket(in_augment->container_slot, augmented_item, ItemPacketCharInventory);
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
|
||||
|
||||
//Log.Out(Logs::DebugLevel::Moderate, Logs::Debug, "cslot: %i aslot: %i cidx: %i aidx: %i act: %i dest: %i",
|
||||
|
||||
@ -778,6 +778,11 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
if (spells[spell_id].targettype == ST_AreaNPCOnly && !curmob->IsNPC())
|
||||
continue;
|
||||
// check PC/NPC only flag 1 = PCs, 2 = NPCs
|
||||
if (spells[spell_id].pcnpc_only_flag == 1 && !curmob->IsClient() && !curmob->IsMerc())
|
||||
continue;
|
||||
if (spells[spell_id].pcnpc_only_flag == 2 && (curmob->IsClient() || curmob->IsMerc()))
|
||||
continue;
|
||||
|
||||
if (spells[spell_id].targettype == ST_Ring) {
|
||||
dist_targ = DistanceSquared(static_cast<glm::vec3>(curmob->GetPosition()), caster->GetTargetRingLocation());
|
||||
|
||||
@ -4655,7 +4655,7 @@ Mob *EntityList::GetClosestMobByBodyType(Mob *sender, bodyType BodyType)
|
||||
return ClosestMob;
|
||||
}
|
||||
|
||||
void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, std::list<Mob*> &m_list)
|
||||
void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, int pcnpc, std::list<Mob*> &m_list)
|
||||
{
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
@ -4664,6 +4664,14 @@ void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radiu
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// check PC/NPC only flag 1 = PCs, 2 = NPCs
|
||||
if (pcnpc == 1 && !ptr->IsClient() && !ptr->IsMerc()) {
|
||||
++it;
|
||||
continue;
|
||||
} else if (pcnpc == 2 && (ptr->IsClient() || ptr->IsMerc())) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
float x_diff = ptr->GetX() - start->GetX();
|
||||
float y_diff = ptr->GetY() - start->GetY();
|
||||
float z_diff = ptr->GetZ() - start->GetZ();
|
||||
|
||||
@ -451,7 +451,7 @@ public:
|
||||
void GetObjectList(std::list<Object*> &o_list);
|
||||
void GetDoorsList(std::list<Doors*> &d_list);
|
||||
void GetSpawnList(std::list<Spawn2*> &d_list);
|
||||
void GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, std::list<Mob*> &m_list);
|
||||
void GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, int pcnpc, std::list<Mob*> &m_list);
|
||||
|
||||
void DepopAll(int NPCTypeID, bool StartSpawnTimer = true);
|
||||
|
||||
|
||||
@ -1806,6 +1806,11 @@ void Lua_Mob::ProcessSpecialAbilities(std::string str) {
|
||||
self->ProcessSpecialAbilities(str);
|
||||
}
|
||||
|
||||
uint32 Lua_Mob::GetAppearance() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAppearance();
|
||||
}
|
||||
|
||||
void Lua_Mob::SetAppearance(int app) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetAppearance(static_cast<EmuAppearance>(app));
|
||||
@ -2291,6 +2296,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetSpecialAbilityParam", (void(Lua_Mob::*)(int,int,int))&Lua_Mob::SetSpecialAbilityParam)
|
||||
.def("ClearSpecialAbilities", (void(Lua_Mob::*)(void))&Lua_Mob::ClearSpecialAbilities)
|
||||
.def("ProcessSpecialAbilities", (void(Lua_Mob::*)(std::string))&Lua_Mob::ProcessSpecialAbilities)
|
||||
.def("GetAppearance", (uint32(Lua_Mob::*)(void))&Lua_Mob::GetAppearance)
|
||||
.def("SetAppearance", (void(Lua_Mob::*)(int))&Lua_Mob::SetAppearance)
|
||||
.def("SetAppearance", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetAppearance)
|
||||
.def("SetDestructibleObject", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDestructibleObject)
|
||||
|
||||
@ -348,6 +348,7 @@ public:
|
||||
void ClearSpecialAbilities();
|
||||
void ProcessSpecialAbilities(std::string str);
|
||||
void SetAppearance(int app);
|
||||
uint32 GetAppearance();
|
||||
void SetAppearance(int app, bool ignore_self);
|
||||
void SetDestructibleObject(bool set);
|
||||
bool IsImmuneToSpell(int spell_id, Lua_Mob caster);
|
||||
|
||||
@ -3405,6 +3405,17 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
if(!IsValidSpell(spell_id))
|
||||
return false;
|
||||
|
||||
// these target types skip pcnpc only check (according to dev quotes)
|
||||
// other AE spells this is redundant, oh well
|
||||
// 1 = PCs, 2 = NPCs
|
||||
if (spells[spell_id].pcnpc_only_flag && spells[spell_id].targettype != ST_AETargetHateList &&
|
||||
spells[spell_id].targettype != ST_HateList) {
|
||||
if (spells[spell_id].pcnpc_only_flag == 1 && !spelltar->IsClient() && !spelltar->IsMerc())
|
||||
return false;
|
||||
else if (spells[spell_id].pcnpc_only_flag == 2 && (spelltar->IsClient() || spelltar->IsMerc()))
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 caster_level = level_override > 0 ? level_override : GetCasterLevel(spell_id);
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Casting spell %d on %s with effective caster level %d", spell_id, spelltar->GetName(), caster_level);
|
||||
@ -5623,7 +5634,7 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust)
|
||||
std::list<Mob *> targets_in_range;
|
||||
|
||||
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].range,
|
||||
spells[spell_id].range / 2, targets_in_range);
|
||||
spells[spell_id].range / 2, spells[spell_id].pcnpc_only_flag, targets_in_range);
|
||||
auto iter = targets_in_range.begin();
|
||||
|
||||
float dX = 0;
|
||||
@ -5698,7 +5709,7 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust)
|
||||
std::list<Mob *> targets_in_range;
|
||||
|
||||
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].aoerange,
|
||||
spells[spell_id].aoerange / 2, targets_in_range);
|
||||
spells[spell_id].aoerange / 2, spells[spell_id].pcnpc_only_flag, targets_in_range);
|
||||
auto iter = targets_in_range.begin();
|
||||
|
||||
while (iter != targets_in_range.end()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user