Просмотр исходного кода

Merge branch 'master' of http://cutpon.com:3000/devn00b/EQ2EMu

# Conflicts:
#	EQ2/source/WorldServer/Spawn.cpp
#	server/EQ2World__Debug_x64.exe
#	server/SpawnStructs.xml
LethalEncounter 4 лет назад
Родитель
Сommit
e64b718066

+ 1 - 0
DB/updates/findspawn_command.sql

@@ -0,0 +1 @@
+insert into commands set handler=521,command='findspawn',required_status=200,subcommand='';

Разница между файлами не показана из-за своего большого размера
+ 43 - 0
DB/updates/fixed_emotes_table.sql


+ 5 - 0
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -4379,6 +4379,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 		case SAVE_AA_PROFILE			: { Save_AA_Profile(client, sep); break; }
 		case COMMAND_TARGETITEM			: { Command_TargetItem(client, sep); break; }
 
+		case COMMAND_FINDSPAWN: { Command_FindSpawn(client, sep); break; }
 
 
 		default: 
@@ -10218,3 +10219,7 @@ void Commands::Command_TargetItem(Client* client, Seperator* sep) {
 		}
 	}
 }
+
+void Commands::Command_FindSpawn(Client* client, Seperator* sep) {
+	client->GetCurrentZone()->FindSpawn(client, (char*)sep->argplus[0]);
+}

+ 4 - 0
EQ2/source/WorldServer/Commands/Commands.h

@@ -468,6 +468,8 @@ public:
 	void Command_DeclineResurrection(Client* client, Seperator* set);
 	void Command_TargetItem(Client* client, Seperator* set);
 
+	void Command_FindSpawn(Client* client, Seperator* set);
+
 	// Bot Commands
 	void Command_Bot(Client* client, Seperator* sep);
 	void Command_Bot_Create(Client* client, Seperator* sep);
@@ -899,6 +901,8 @@ private:
 #define COMMAND_RELOAD_RULES			519
 #define COMMAND_RELOAD_TRANSPORTERS		520
 
+#define COMMAND_FINDSPAWN				521
+
 #define GET_AA_XML						751
 #define ADD_AA							752
 #define COMMIT_AA_PROFILE				753				

+ 3 - 2
EQ2/source/WorldServer/Player.cpp

@@ -54,6 +54,7 @@ Player::Player(){
 	spawn_index = 0;
 	info = 0;
 	movement_packet = 0;
+	fully_logged_in = false;
 	last_movement_activity = 0;
 	//speed = 0;
 	packet_num = 0;
@@ -578,7 +579,7 @@ void PlayerInfo::SetAccountAge(int16 age){
 
 EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyValue) {
 	player->CalculateBonuses();
-	info_struct->heat = 15;
+/*	info_struct->heat = 15;
 	info_struct->heat_base = 13;
 	info_struct->divine = 14;
 	info_struct->divine_base = 11;
@@ -587,7 +588,7 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 	info_struct->coin_copper = 1;
 	info_struct->coin_silver = 2;
 	info_struct->coin_gold = 3;
-	info_struct->coin_plat = 4;
+	info_struct->coin_plat = 4;*/
 
 	int8 blah1 = 90;
 	int8 blah2 = 120;

+ 9 - 1
EQ2/source/WorldServer/Spawn.cpp

@@ -2391,7 +2391,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 		temp_activity_status = 1;
 
 	temp_activity_status += (IsNPC() || IsObject() || IsGroundSpawn()) ? 1 << 1 : 0;
-	if (version > 546) {
+	if (version >= 1188) {
 		if (IsGroundSpawn() || GetShowHandIcon())
 			temp_activity_status += ACTIVITY_STATUS_INTERACTABLE_1188;
 
@@ -2429,14 +2429,22 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 			temp_activity_status += ACTIVITY_STATUS_INCOMBAT_1188;
 
 		// if this is either a boat or lift let the client be manipulated by the object
+		// doesn't work for DoF client version 546
 		if (appearance.icon == 28 || appearance.icon == 12)
+		{
 			temp_activity_status += ACTIVITY_STATUS_ISTRANSPORT_1188;
+		}
 	}
 	else
 	{
 		temp_activity_status = appearance.activity_status;
 		if(IsNPC())
 			temp_activity_status = 0xFF;
+
+		// this only partially fixes lifts in classic 283 client if you move just as the lift starts to move
+		if (appearance.icon == 28 || appearance.icon == 12)
+			packet->setDataByName("is_transport", 1);
+
 		if (MeetsSpawnAccessRequirements(spawn))
 			packet->setDataByName("hand_icon", appearance.display_hand_icon);
 		else {

+ 114 - 7
EQ2/source/WorldServer/VisualStates.h

@@ -17,6 +17,7 @@
     You should have received a copy of the GNU General Public License
     along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
 */
+#include "../common/Log.h"
 #include <map>
 
 using namespace std;
@@ -47,7 +48,6 @@ private:
 	int id;
 	string name;
 };
-
 class Emote{
 public:
 	Emote(char* in_name, int in_visual_state, char* in_message, char* in_targeted_message){
@@ -74,6 +74,97 @@ private:
 	string message;
 	string targeted_message;
 };
+class VersionRange {
+public:
+	VersionRange(int32 in_min_version, int32 in_max_version)
+	{
+		min_version = in_min_version;
+		max_version = in_max_version;
+	}
+	int32 GetMinVersion() { return min_version; }
+	int32 GetMaxVersion() { return max_version; }
+private:
+	int32 min_version;
+	int32 max_version;
+};
+
+class EmoteVersionRange {
+public:
+	EmoteVersionRange(char* in_name)
+	{
+		name = string(in_name);
+	}
+
+	~EmoteVersionRange()
+	{
+		map<VersionRange*, Emote*>::iterator itr;
+		for (itr = version_map.begin(); itr != version_map.end(); itr++)
+		{
+			VersionRange* range = itr->first;
+			Emote* emote = itr->second;
+			delete range;
+			delete emote;
+		}
+
+		version_map.clear();
+	}
+
+	void AddVersionRange(int32 min_version, int32 max_version,
+		char* in_name, int in_visual_state, char* in_message, char* in_targeted_message)
+	{
+		map<VersionRange*, Emote*>::iterator itr = FindVersionRange(min_version, max_version);
+		if (itr != version_map.end())
+		{
+			VersionRange* range = itr->first;
+			LogWrite(WORLD__ERROR, 0, "Emotes Table Error: Duplicate emote mapping of %s with range min %u max %u, Existing found with range min %u max %u\n", name.c_str(), min_version, max_version, range->GetMinVersion(), range->GetMaxVersion());
+			return;
+		}
+
+		version_map.insert(make_pair(new VersionRange(min_version, max_version), new Emote(in_name, in_visual_state, in_message, in_targeted_message)));
+	}
+
+	map<VersionRange*, Emote*>::iterator FindVersionRange(int32 min_version, int32 max_version)
+	{
+		map<VersionRange*, Emote*>::iterator itr;
+		for (itr = version_map.begin(); itr != version_map.end(); itr++)
+		{
+			VersionRange* range = itr->first;
+			// if min and max version are both in range
+			if (range->GetMinVersion() <= min_version && max_version <= range->GetMaxVersion())
+				return itr;
+			// if the min version is in range, but max range is 0
+			else if (range->GetMinVersion() <= min_version && range->GetMaxVersion() == 0)
+				return itr;
+			// if min version is 0 and max_version has a cap
+			else if (range->GetMinVersion() == 0 && max_version <= range->GetMaxVersion())
+				return itr;
+		}
+
+		return version_map.end();
+	}
+
+	map<VersionRange*, Emote*>::iterator FindEmoteVersion(int32 version)
+	{
+		map<VersionRange*, Emote*>::iterator itr;
+		for (itr = version_map.begin(); itr != version_map.end(); itr++)
+		{
+			VersionRange* range = itr->first;
+			// if min and max version are both in range
+			if (version >= range->GetMinVersion() && (range->GetMaxVersion() == 0 || version <= range->GetMaxVersion()))
+				return itr;
+		}
+
+		return version_map.end();
+	}
+
+	const char* GetName() { return name.c_str(); }
+	string GetNameString() { return name; }
+
+	map<VersionRange*, Emote*>::iterator GetRangeEnd() { return version_map.end(); }
+private:
+	map<VersionRange*, Emote*> version_map;
+	string name;
+};
 
 class VisualStates
 {
@@ -88,7 +179,7 @@ public:
 	}
 
 	void ClearEmotes(){
-		map<string, Emote*>::iterator map_list;
+		map<string, EmoteVersionRange*>::iterator map_list;
 		for(map_list = emoteMap.begin(); map_list != emoteMap.end(); map_list++ )
 			safe_delete(map_list->second);
 		emoteMap.clear();
@@ -111,17 +202,33 @@ public:
 		return 0;
 	}
 
-	void InsertEmote(Emote* emote){
-		emoteMap[emote->GetNameString()] = emote;
+	void InsertEmoteRange(EmoteVersionRange* emote) {
+		emoteMap[emote->GetName()] = emote;
 	}
 
-	Emote* FindEmote(string var){
-		if(emoteMap.count(var) > 0)
+	EmoteVersionRange* FindEmoteRange(string var) {
+		if (emoteMap.count(var) > 0)
+		{
 			return emoteMap[var];
+		}
+		return 0;
+	}
+
+	Emote* FindEmote(string var, int32 version){
+		if (emoteMap.count(var) > 0)
+		{
+			map<VersionRange*,Emote*>::iterator itr = emoteMap[var]->FindEmoteVersion(version);
+
+			if (itr != emoteMap[var]->GetRangeEnd())
+			{
+				Emote* emote = itr->second;
+				return emote;
+			}
+		}
 		return 0;
 	}
 private:
 	map<string,VisualState*> visualStateMap;
-	map<string,Emote*> emoteMap;
+	map<string,EmoteVersionRange*> emoteMap;
 };
 

+ 9 - 3
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -429,11 +429,17 @@ void WorldDatabase::LoadVisualStates()
 	LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u visual states", total);
 
 	total = 0;
-	result = query2.RunQuery2(Q_SELECT, "SELECT name, visual_state_id, message, targeted_message FROM emotes");
+	result = query2.RunQuery2(Q_SELECT, "SELECT name, visual_state_id, message, targeted_message, min_version_range, max_version_range FROM emotes");
 	while(result && (row = mysql_fetch_row(result)))
 	{
-		Emote* emote = new Emote(row[0], atoi(row[1]), row[2], row[3]);
-		visual_states.InsertEmote(emote);
+		EmoteVersionRange* range = 0;
+		if ((range = visual_states.FindEmoteRange(string(row[0]))) == NULL)
+		{
+			range = new EmoteVersionRange(row[0]);
+			visual_states.InsertEmoteRange(range);
+		}
+		
+		range->AddVersionRange(atoul(row[4]),atoul(row[5]), row[0], atoi(row[1]), row[2], row[3]);
 		total++;
 		LogWrite(WORLD__DEBUG, 5, "World", "---Loading emote state: '%s' (%i)", row[1], atoi(row[0]));
 	}

+ 70 - 0
EQ2/source/WorldServer/Zone/mob_movement_manager.cpp

@@ -587,6 +587,13 @@ void MobMovementManager::RotateTo(Entity *who, float to, MobMovementMode mob_mov
 {
 	MobListMutex.readlock();
 	auto iter = _impl->Entries.find(who);
+
+	if (iter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent = (*iter);
 
 	if (true != ent.second.Commands.empty()) {
@@ -608,6 +615,13 @@ void MobMovementManager::Teleport(Entity *who, float x, float y, float z, float
 {
 	MobListMutex.readlock();
 	auto iter = _impl->Entries.find(who);
+
+	if (iter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent = (*iter);
 
 	ent.second.Commands.clear();
@@ -633,6 +647,13 @@ void MobMovementManager::NavigateTo(Entity *who, float x, float y, float z, MobM
 	}
 	MobListMutex.readlock();
 	auto iter = _impl->Entries.find(who);
+
+	if (iter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent = (*iter);
 	auto &nav = ent.second.NavTo;
 
@@ -693,6 +714,13 @@ void MobMovementManager::StopNavigation(Entity *who)
 {
 	MobListMutex.readlock();
 	auto iter = _impl->Entries.find(who);
+
+	if (iter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent = (*iter);
 	auto &nav = ent.second.NavTo;
 
@@ -728,6 +756,13 @@ void MobMovementManager::DisruptNavigation(Entity* who)
 {
 	MobListMutex.readlock();
 	auto iter = _impl->Entries.find(who);
+
+	if (iter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto& ent = (*iter);
 	auto& nav = ent.second.NavTo;
 
@@ -786,6 +821,13 @@ void MobMovementManager::UpdatePath(Entity *who, float x, float y, float z, MobM
 	if (!who->GetZone()->zonemap /*|| !zone->HasWaterMap()*/) {
 		MobListMutex.readlock();
 		auto iter = _impl->Entries.find(who);
+
+		if (iter == _impl->Entries.end())
+		{
+			MobListMutex.releasereadlock();
+			return; // does not exist in navigation
+		}
+
 		auto &ent = (*iter);
 
 		PushMoveTo(ent.second, x, y, z, mob_movement_mode);
@@ -833,6 +875,13 @@ void MobMovementManager::UpdatePathGround(Entity *who, float x, float y, float z
 
 	MobListMutex.readlock();
 	auto eiter = _impl->Entries.find(who);
+
+	if (eiter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent  = (*eiter);
 
 	if (route.size() == 0) {
@@ -960,6 +1009,13 @@ void MobMovementManager::UpdatePathUnderwater(Entity *who, float x, float y, flo
 {
 	MobListMutex.readlock();
 	auto eiter = _impl->Entries.find(who);
+
+	if (eiter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent  = (*eiter);
 	if (/*zone->watermap->InLiquid(who->GetPosition()) && zone->watermap->InLiquid(glm::vec3(x, y, z)) &&*/
 		who->GetZone()->zonemap->CheckLoS(glm::vec3(who->GetX(),who->GetZ(),who->GetY()), glm::vec3(x, y, z))) {
@@ -1081,6 +1137,13 @@ void MobMovementManager::UpdatePathBoat(Entity *who, float x, float y, float z,
 {
 	MobListMutex.readlock();
 	auto eiter = _impl->Entries.find(who);
+
+	if (eiter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent  = (*eiter);
 
 	PushSwimTo(ent.second, x, y, z, mode);
@@ -1188,6 +1251,13 @@ void MobMovementManager::HandleStuckBehavior(Entity *who, float x, float y, floa
 	}
 
 	auto eiter = _impl->Entries.find(who);
+
+	if (eiter == _impl->Entries.end())
+	{
+		MobListMutex.releasereadlock();
+		return; // does not exist in navigation
+	}
+
 	auto &ent = (*eiter);
 
 	switch (sb) {

+ 11 - 8
EQ2/source/WorldServer/client.cpp

@@ -973,12 +973,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	case OP_SysClient: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_SysClient", opcode, opcode);
 		LogWrite(CCLIENT__DEBUG, 0, "Client", "Client '%s' (%u) is ready for spawn updates.", GetPlayer()->GetName(), GetPlayer()->GetCharacterID());
-		GetPlayer()->SetFullyLoggedIn(true);
-
-		if (!ready_for_updates)
-			database.loadCharacterProperties(this);
-
-		ready_for_updates = true;
+		SetReadyForUpdates();
 		break;
 	}
 	case OP_MapRequest: {
@@ -1533,8 +1528,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 			EQ2_16BitString str = packet->getType_EQ2_16BitString_ByName("signal");
 			if (str.size > 0) {
 				if (strcmp(str.data.c_str(), "sys_client_avatar_ready") == 0) {
-					GetPlayer()->SetFullyLoggedIn(true);
-					ready_for_updates = true;
+					SetReadyForUpdates();
 					GetPlayer()->SendSpawnChanges(true);
 				}
 				const char* zone_script = world.GetZoneScript(player->GetZone()->GetZoneID());
@@ -7541,6 +7535,15 @@ void Client::SearchStore(int32 page) {
 
 }
 
+void Client::SetReadyForUpdates() {
+	GetPlayer()->SetFullyLoggedIn(true);
+
+	if (!ready_for_updates)
+		database.loadCharacterProperties(this);
+
+	ready_for_updates = true;
+}
+
 void Client::SetReadyForSpawns(bool val) {
 	ready_for_spawns = val;
 	if (GetPlayer()->GetActivityStatus() > 0) {

+ 1 - 0
EQ2/source/WorldServer/client.h

@@ -146,6 +146,7 @@ public:
 	bool	IsReadyForSpawns(){ return ready_for_spawns; }
 	bool	IsReadyForUpdates() { return ready_for_updates; }
 	bool	IsZoning(){ return client_zoning; }
+	void	SetReadyForUpdates();
 	void	SetReadyForSpawns(bool val);
 	void	QueuePacket(EQ2Packet* app, bool attemptedCombine=false);
 	void	SendLoginInfo();

+ 84 - 2
EQ2/source/WorldServer/zoneserver.cpp

@@ -25,6 +25,7 @@ using namespace std;
 #include <stdio.h>
 #include <time.h>
 #include <stdlib.h>
+#include <regex>
 #include "Commands/Commands.h"
 #include "Zone/pathfinder_interface.h"
 
@@ -5661,20 +5662,44 @@ void ZoneServer::HandleEmote(Client* originator, string name) {
 	}
 
 	Client* client = 0;
-	Emote* emote = visual_states.FindEmote(name);
-	if(!emote){
+	Emote* origEmote = visual_states.FindEmote(name, originator->GetVersion());
+	if(!origEmote){
 		originator->Message(CHANNEL_COLOR_YELLOW, "Unable to find emote '%s'.  If this should be a valid emote be sure to submit a /bug report.", name.c_str());
 		return;
 	}
+	Emote* emote = origEmote;
+
 	PacketStruct* packet = 0;
 	char* emoteResponse = 0;
 	vector<Client*>::iterator client_itr;
 	
+	int32 cur_client_version = originator->GetVersion();
+	map<int32, Emote*> emote_version_range;
 	MClientList.readlock(__FUNCTION__, __LINE__);
 	for (client_itr = clients.begin(); client_itr != clients.end(); client_itr++) {
 		client = *client_itr;
 		if(!client || (client && client->GetPlayer()->IsIgnored(originator->GetPlayer()->GetName())))
 			continue;
+
+		// establish appropriate emote for the version used by the client
+		if (client->GetVersion() != originator->GetVersion())
+		{
+			map<int32, Emote*>::iterator rangeitr = emote_version_range.find(client->GetVersion());
+			if (rangeitr == emote_version_range.end())
+			{
+				Emote* tmp_new_emote = visual_states.FindEmote(name, client->GetVersion());
+				if (tmp_new_emote)
+				{
+					emote_version_range.insert(make_pair(client->GetVersion(), tmp_new_emote));
+					emote = tmp_new_emote;
+				} // else its missing just use the current clients default
+			}
+			else // we have an existing emote already cached
+				emote = rangeitr->second;
+		}
+		else // since the client and originator client match use the original emote
+			emote = origEmote;
+
 		packet = configReader.getStruct("WS_CannedEmote", client->GetVersion());
 		if(packet){
 			packet->setDataByName("spawn_id" , client->GetPlayer()->GetIDWithPlayerSpawn(originator->GetPlayer()));
@@ -5816,6 +5841,63 @@ bool ZoneServer::SendRadiusSpawnInfo(Client* client, float radius) {
 	return ret;
 }
 
+void ZoneServer::FindSpawn(Client* client, char* regSearchStr)
+{
+	if (!regSearchStr || strlen(regSearchStr) < 1)
+	{
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Bad ZoneServer::FindSpawn(Client*, char* regSearchStr) attempt, regSearchStr is NULL or empty.");
+		return;
+	}
+
+	string resString = string(regSearchStr);
+	try
+	{
+		std::regex pre_re_check("^[a-zA-Z0-9_ ]+$");
+		bool output = std::regex_match(resString, pre_re_check);
+		if (output)
+		{
+			string newStr(".*");
+			newStr.append(regSearchStr);
+			newStr.append(".*");
+			resString = newStr;
+		}
+	}
+	catch (...)
+	{
+		client->SimpleMessage(CHANNEL_COLOR_RED, "Try/Catch ZoneServer::FindSpawn(Client*, char* regSearchStr) failure.");
+		return;
+	}
+	client->Message(CHANNEL_COLOR_WHITE, "RegEx Search Spawn List: %s", regSearchStr);
+	client->Message(CHANNEL_COLOR_WHITE, "Database ID | Spawn Name | X , Y , Z");
+	client->Message(CHANNEL_COLOR_WHITE, "========================");
+	map<int32, Spawn*>::iterator itr;
+	MSpawnList.readlock(__FUNCTION__, __LINE__);
+	int32 spawnsFound = 0;
+	std::regex re(resString, std::regex_constants::icase);
+	for (itr = spawn_list.begin(); itr != spawn_list.end(); itr++) {
+		Spawn* spawn = itr->second;
+		if (!spawn || !spawn->GetName())
+			continue;
+		bool output = false;
+		try {
+			output = std::regex_match(string(spawn->GetName()), re);
+		}
+		catch (...)
+		{
+			continue;
+		}
+
+		if (output)
+		{
+			client->Message(CHANNEL_COLOR_WHITE, "%i | %s | %f , %f , %f", spawn->GetDatabaseID(), spawn->GetName(), spawn->GetX(), spawn->GetY(), spawn->GetZ());
+			spawnsFound++;
+		}
+	}
+	client->Message(CHANNEL_COLOR_WHITE, "========================", spawnsFound);
+	client->Message(CHANNEL_COLOR_WHITE, "%u Results Found.", spawnsFound);
+	MSpawnList.releasereadlock(__FUNCTION__, __LINE__);
+}
+
 
 void ZoneServer::AddPlayerTracking(Player* player) {
 	if (player && !player->GetIsTracking() && players_tracking.count(player->GetDatabaseID()) == 0) {

+ 2 - 1
EQ2/source/WorldServer/zoneserver.h

@@ -345,8 +345,9 @@ public:
 	void	CheckTransporters(Client* client);
 	
 	void	WritePlayerStatistics();
-	
+
 	bool	SendRadiusSpawnInfo(Client* client, float radius);
+	void	FindSpawn(Client* client, char* regSearchStr);
 
 	volatile bool	spawnthread_active;
 	volatile bool	combatthread_active;

+ 2 - 2
EQ2/source/common/version.h

@@ -38,9 +38,9 @@
 #endif
 
 #if defined(LOGIN)
-#define CURRENT_VERSION	"0.8.1-cancer2"
+#define CURRENT_VERSION	"0.8.1-leo1"
 #elif defined(WORLD)
-#define CURRENT_VERSION	"0.8.1-cancer2"
+#define CURRENT_VERSION	"0.8.1-leo1"
 #else
 #define CURRENT_VERSION	"0.7.3-dev"
 #endif

BIN
server/EQ2Login__Debug64.exe


BIN
server/EQ2World__Debug_x64.exe


+ 3 - 3
server/SpawnStructs.xml

@@ -373,7 +373,7 @@
 <Data ElementName="no_arrow_color_or_healthbar" Type="int8" Size="1" /> <!-- 37 -->
 <Data ElementName="hand_icon" Type="int8" Size="1" /> <!-- 38   127 -->
 <Data ElementName="hide_health" Type="int8" Size="1" /> <!-- 39 -->
-<Data ElementName="unknown15" Type="int8" Size="1" /> <!-- 40 -->
+<Data ElementName="is_transport" Type="int8" Size="1" /> <!-- 40 -->
 <Data ElementName="house_icon" Type="int8" Size="1" /> <!-- 41 -->
 <Data ElementName="in_combat" Type="int8" Size="1" /> <!-- 42 -->
 <Data ElementName="afk" Type="int8" Size="1" /> <!-- 43 -->
@@ -462,9 +462,9 @@
 <Data ElementName="unknown10" Type="int8" Size="1" /> <!-- 306 -->
 <Data ElementName="no_arrow_color_or_highlight" Type="int8" Size="1" /> <!-- 307 -->
 <Data ElementName="no_arrow_color_or_healthbar" Type="int8" Size="1" /> <!-- 308 -->
-<Data ElementName="hand_icon" Type="int8" Size="1" /> <!-- 309   127 -->
+<Data ElementName="hand_icon" Type="int8" Size="1" /> <!-- 309 -->
 <Data ElementName="hide_health" Type="int8" Size="1" /> <!-- 310 -->
-<Data ElementName="unknown11" Type="int8" Size="1" /> <!-- 311 -->
+<Data ElementName="is_transport" Type="int8" Size="1" /> <!-- 311 -->
 <Data ElementName="house_icon" Type="int8" Size="1" /> <!-- 312 -->
 <Data ElementName="in_combat" Type="int8" Size="1" /> <!-- 313 -->
 <Data ElementName="afk" Type="int8" Size="1" /> <!-- 314 -->

Некоторые файлы не были показаны из-за большого количества измененных файлов