Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions common/database/database_update_manifest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7099,19 +7099,30 @@ ALTER TABLE `npc_types`
)",
.content_schema_update = true
},
ManifestEntry{
.version = 9323,
.description = "2025_04_16_character_data_first_login.sql",
.check = "SHOW COLUMNS FROM `character_data` LIKE 'first_login'",
.condition = "empty",
.match = "",
.sql = R"(
ManifestEntry{
.version = 9323,
.description = "2025_04_16_character_data_first_login.sql",
.check = "SHOW COLUMNS FROM `character_data` LIKE 'first_login'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_data`
CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`,
ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`;
)",
.content_schema_update = false
},
.content_schema_update = false
},
ManifestEntry{
.version = 9324,
.description = "2025_06_01_zonepoints_target_version.sql",
.check = "SHOW COLUMNS FROM `zone_points` LIKE 'target_version'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `zone_points` ADD COLUMN `target_version` INT NOT NULL DEFAULT 0 AFTER `target_zone_id`;
)",
.content_schema_update = false
},
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
// .version = 9228,
Expand Down
146 changes: 79 additions & 67 deletions common/repositories/base/base_zone_points_repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ class BaseZonePointsRepository {
float target_z;
float target_heading;
uint16_t zoneinst;
uint32_t target_zone_id;
uint32_t target_instance;
uint32_t target_zone_id;
int32_t target_version;
uint32_t target_instance;
float buffer;
uint32_t client_version_mask;
int8_t min_expansion;
Expand Down Expand Up @@ -65,9 +66,10 @@ class BaseZonePointsRepository {
"target_x",
"target_z",
"target_heading",
"zoneinst",
"target_zone_id",
"target_instance",
"zoneinst",
"target_zone_id",
"target_version",
"target_instance",
"buffer",
"client_version_mask",
"min_expansion",
Expand Down Expand Up @@ -95,9 +97,10 @@ class BaseZonePointsRepository {
"target_x",
"target_z",
"target_heading",
"zoneinst",
"target_zone_id",
"target_instance",
"zoneinst",
"target_zone_id",
"target_version",
"target_instance",
"buffer",
"client_version_mask",
"min_expansion",
Expand Down Expand Up @@ -160,8 +163,9 @@ class BaseZonePointsRepository {
e.target_z = 0;
e.target_heading = 0;
e.zoneinst = 0;
e.target_zone_id = 0;
e.target_instance = 0;
e.target_zone_id = 0;
e.target_version = 0;
e.target_instance = 0;
e.buffer = 0;
e.client_version_mask = 4294967295;
e.min_expansion = -1;
Expand Down Expand Up @@ -220,17 +224,18 @@ class BaseZonePointsRepository {
e.target_z = row[10] ? strtof(row[10], nullptr) : 0;
e.target_heading = row[11] ? strtof(row[11], nullptr) : 0;
e.zoneinst = row[12] ? static_cast<uint16_t>(strtoul(row[12], nullptr, 10)) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_instance = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.buffer = row[15] ? strtof(row[15], nullptr) : 0;
e.client_version_mask = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 4294967295;
e.min_expansion = row[17] ? static_cast<int8_t>(atoi(row[17])) : -1;
e.max_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.content_flags = row[19] ? row[19] : "";
e.content_flags_disabled = row[20] ? row[20] : "";
e.is_virtual = row[21] ? static_cast<int8_t>(atoi(row[21])) : 0;
e.height = row[22] ? static_cast<int32_t>(atoi(row[22])) : 0;
e.width = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_version = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.target_instance = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.buffer = row[16] ? strtof(row[16], nullptr) : 0;
e.client_version_mask = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 4294967295;
e.min_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.max_expansion = row[19] ? static_cast<int8_t>(atoi(row[19])) : -1;
e.content_flags = row[20] ? row[20] : "";
e.content_flags_disabled = row[21] ? row[21] : "";
e.is_virtual = row[22] ? static_cast<int8_t>(atoi(row[22])) : 0;
e.height = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.width = row[24] ? static_cast<int32_t>(atoi(row[24])) : 0;

return e;
}
Expand Down Expand Up @@ -275,18 +280,19 @@ class BaseZonePointsRepository {
v.push_back(columns[9] + " = " + std::to_string(e.target_x));
v.push_back(columns[10] + " = " + std::to_string(e.target_z));
v.push_back(columns[11] + " = " + std::to_string(e.target_heading));
v.push_back(columns[12] + " = " + std::to_string(e.zoneinst));
v.push_back(columns[13] + " = " + std::to_string(e.target_zone_id));
v.push_back(columns[14] + " = " + std::to_string(e.target_instance));
v.push_back(columns[15] + " = " + std::to_string(e.buffer));
v.push_back(columns[16] + " = " + std::to_string(e.client_version_mask));
v.push_back(columns[17] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[18] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[19] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[20] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
v.push_back(columns[21] + " = " + std::to_string(e.is_virtual));
v.push_back(columns[22] + " = " + std::to_string(e.height));
v.push_back(columns[23] + " = " + std::to_string(e.width));
v.push_back(columns[12] + " = " + std::to_string(e.zoneinst));
v.push_back(columns[13] + " = " + std::to_string(e.target_zone_id));
v.push_back(columns[14] + " = " + std::to_string(e.target_version));
v.push_back(columns[15] + " = " + std::to_string(e.target_instance));
v.push_back(columns[16] + " = " + std::to_string(e.buffer));
v.push_back(columns[17] + " = " + std::to_string(e.client_version_mask));
v.push_back(columns[18] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[19] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[20] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[21] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
v.push_back(columns[22] + " = " + std::to_string(e.is_virtual));
v.push_back(columns[23] + " = " + std::to_string(e.height));
v.push_back(columns[24] + " = " + std::to_string(e.width));

auto results = db.QueryDatabase(
fmt::format(
Expand Down Expand Up @@ -320,9 +326,10 @@ class BaseZonePointsRepository {
v.push_back(std::to_string(e.target_x));
v.push_back(std::to_string(e.target_z));
v.push_back(std::to_string(e.target_heading));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_version));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.min_expansion));
Expand Down Expand Up @@ -373,9 +380,10 @@ class BaseZonePointsRepository {
v.push_back(std::to_string(e.target_x));
v.push_back(std::to_string(e.target_z));
v.push_back(std::to_string(e.target_heading));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_version));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.min_expansion));
Expand Down Expand Up @@ -431,17 +439,18 @@ class BaseZonePointsRepository {
e.target_z = row[10] ? strtof(row[10], nullptr) : 0;
e.target_heading = row[11] ? strtof(row[11], nullptr) : 0;
e.zoneinst = row[12] ? static_cast<uint16_t>(strtoul(row[12], nullptr, 10)) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_instance = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.buffer = row[15] ? strtof(row[15], nullptr) : 0;
e.client_version_mask = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 4294967295;
e.min_expansion = row[17] ? static_cast<int8_t>(atoi(row[17])) : -1;
e.max_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.content_flags = row[19] ? row[19] : "";
e.content_flags_disabled = row[20] ? row[20] : "";
e.is_virtual = row[21] ? static_cast<int8_t>(atoi(row[21])) : 0;
e.height = row[22] ? static_cast<int32_t>(atoi(row[22])) : 0;
e.width = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_version = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.target_instance = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.buffer = row[16] ? strtof(row[16], nullptr) : 0;
e.client_version_mask = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 4294967295;
e.min_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.max_expansion = row[19] ? static_cast<int8_t>(atoi(row[19])) : -1;
e.content_flags = row[20] ? row[20] : "";
e.content_flags_disabled = row[21] ? row[21] : "";
e.is_virtual = row[22] ? static_cast<int8_t>(atoi(row[22])) : 0;
e.height = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.width = row[24] ? static_cast<int32_t>(atoi(row[24])) : 0;

all_entries.push_back(e);
}
Expand Down Expand Up @@ -479,17 +488,18 @@ class BaseZonePointsRepository {
e.target_z = row[10] ? strtof(row[10], nullptr) : 0;
e.target_heading = row[11] ? strtof(row[11], nullptr) : 0;
e.zoneinst = row[12] ? static_cast<uint16_t>(strtoul(row[12], nullptr, 10)) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_instance = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.buffer = row[15] ? strtof(row[15], nullptr) : 0;
e.client_version_mask = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 4294967295;
e.min_expansion = row[17] ? static_cast<int8_t>(atoi(row[17])) : -1;
e.max_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.content_flags = row[19] ? row[19] : "";
e.content_flags_disabled = row[20] ? row[20] : "";
e.is_virtual = row[21] ? static_cast<int8_t>(atoi(row[21])) : 0;
e.height = row[22] ? static_cast<int32_t>(atoi(row[22])) : 0;
e.width = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.target_zone_id = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.target_version = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.target_instance = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.buffer = row[16] ? strtof(row[16], nullptr) : 0;
e.client_version_mask = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 4294967295;
e.min_expansion = row[18] ? static_cast<int8_t>(atoi(row[18])) : -1;
e.max_expansion = row[19] ? static_cast<int8_t>(atoi(row[19])) : -1;
e.content_flags = row[20] ? row[20] : "";
e.content_flags_disabled = row[21] ? row[21] : "";
e.is_virtual = row[22] ? static_cast<int8_t>(atoi(row[22])) : 0;
e.height = row[23] ? static_cast<int32_t>(atoi(row[23])) : 0;
e.width = row[24] ? static_cast<int32_t>(atoi(row[24])) : 0;

all_entries.push_back(e);
}
Expand Down Expand Up @@ -576,9 +586,10 @@ class BaseZonePointsRepository {
v.push_back(std::to_string(e.target_x));
v.push_back(std::to_string(e.target_z));
v.push_back(std::to_string(e.target_heading));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_version));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.min_expansion));
Expand Down Expand Up @@ -622,9 +633,10 @@ class BaseZonePointsRepository {
v.push_back(std::to_string(e.target_x));
v.push_back(std::to_string(e.target_z));
v.push_back(std::to_string(e.target_heading));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.zoneinst));
v.push_back(std::to_string(e.target_zone_id));
v.push_back(std::to_string(e.target_version));
v.push_back(std::to_string(e.target_instance));
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.min_expansion));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE zone_points ADD COLUMN target_version INT NOT NULL DEFAULT 0 AFTER target_zone_id;
41 changes: 27 additions & 14 deletions zone/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6988,12 +6988,14 @@ void Client::SendZonePoints()
// if we don't use the same instance_id that the client was sent, the client will forcefully
// issue a zone change request when they should be simply moving to a different point in the same zone
// because the client will think the zone point target is different from the current instance
auto target_instance = data->target_zone_instance;
if (data->target_zone_id == zone->GetZoneID() && data->target_zone_instance == 0) {
target_instance = zone->GetInstanceID();
}

zp->zpe[i].zoneinstance = target_instance;
auto target_instance = data->target_zone_instance;
if (data->target_zone_id == zone->GetZoneID() && data->target_zone_instance == 0 && data->target_version == 0) {
target_instance = zone->GetInstanceID();
} else if (data->target_zone_instance == 0 && data->target_version != 0) {
target_instance = data->target_version;
}

zp->zpe[i].zoneinstance = target_instance;
i++;
}
iterator.Advance();
Expand Down Expand Up @@ -9872,14 +9874,25 @@ void Client::CheckVirtualZoneLines()
GetZ() < (virtual_zone_point.z + (float) virtual_zone_point.height)
) {

MovePC(
virtual_zone_point.target_zone_id,
virtual_zone_point.target_instance,
virtual_zone_point.target_x,
virtual_zone_point.target_y,
virtual_zone_point.target_z,
virtual_zone_point.target_heading
);
if (virtual_zone_point.target_instance == 0 && virtual_zone_point.target_version != 0) {
MovePC(
virtual_zone_point.target_zone_id,
virtual_zone_point.target_version,
virtual_zone_point.target_x,
virtual_zone_point.target_y,
virtual_zone_point.target_z,
virtual_zone_point.target_heading
);
} else {
MovePC(
virtual_zone_point.target_zone_id,
virtual_zone_point.target_instance,
virtual_zone_point.target_x,
virtual_zone_point.target_y,
virtual_zone_point.target_z,
virtual_zone_point.target_heading
);
}

LogZonePoints(
"Virtual Zone Box Sending player [{}] to [{}]",
Expand Down
3 changes: 2 additions & 1 deletion zone/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,8 @@ class Client : public Mob
void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MovePC(uint32 zoneID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MovePC(float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MovePC(uint32 zoneID, int16 version, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MoveZone(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f));
void MoveZoneGroup(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f));
void MoveZoneRaid(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f));
Expand Down
Loading