Commit db8eac67 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro into server

parents 08c178c4 2c3d2e48
......@@ -1208,8 +1208,8 @@ bool ClientField::CheckSelectSum() {
int mm = -1, mx = -1, max = 0, sumc = 0;
bool ret = false;
for (auto sc : selected_cards) {
int op1 = sc->opParam & 0xffff;
int op2 = sc->opParam >> 16;
int op1, op2;
get_sum_params(sc->opParam, op1, op2);
int opmin = (op2 > 0 && op1 > op2) ? op2 : op1;
int opmax = op2 > op1 ? op2 : op1;
if (mm == -1 || opmin < mm)
......@@ -1224,8 +1224,8 @@ bool ClientField::CheckSelectSum() {
if (select_sumval <= max && select_sumval > max - mx)
ret = true;
for(auto sc : selable) {
int op1 = sc->opParam & 0xffff;
int op2 = sc->opParam >> 16;
int op1, op2;
get_sum_params(sc->opParam, op1, op2);
int m = op1;
int sums = sumc;
sums += m;
......@@ -1291,11 +1291,19 @@ bool ClientField::CheckSelectTribute() {
}
return ret;
}
void ClientField::get_sum_params(unsigned int opParam, int& op1, int& op2) {
op1 = opParam & 0xffff;
op2 = (opParam >> 16) & 0xffff;
if (op2 & 0x8000) {
op1 = opParam & 0x7fffffff;
op2 = 0;
}
}
bool ClientField::check_min(const std::set<ClientCard*>& left, std::set<ClientCard*>::const_iterator index, int min, int max) {
if (index == left.end())
return false;
int op1 = (*index)->opParam & 0xffff;
int op2 = (*index)->opParam >> 16;
int op1, op2;
get_sum_params((*index)->opParam, op1, op2);
int m = (op2 > 0 && op1 > op2) ? op2 : op1;
if (m >= min && m <= max)
return true;
......@@ -1314,9 +1322,8 @@ bool ClientField::check_sel_sum_s(const std::set<ClientCard*>& left, int index,
check_sel_sum_t(left, acc);
return false;
}
int l = selected_cards[index]->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params(selected_cards[index]->opParam, l1, l2);
bool res1 = false, res2 = false;
res1 = check_sel_sum_s(left, index + 1, acc - l1);
if (l2 > 0)
......@@ -1330,9 +1337,8 @@ void ClientField::check_sel_sum_t(const std::set<ClientCard*>& left, int acc) {
continue;
std::set<ClientCard*> testlist(left);
testlist.erase(*sit);
int l = (*sit)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params((*sit)->opParam, l1, l2);
if (check_sum(testlist.begin(), testlist.end(), acc - l1, count)
|| (l2 > 0 && check_sum(testlist.begin(), testlist.end(), acc - l2, count))) {
selectsum_cards.insert(*sit);
......@@ -1344,9 +1350,8 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se
return count >= select_min && count <= select_max;
if (acc < 0 || index == end)
return false;
int l = (*index)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params((*index)->opParam, l1, l2);
if ((l1 == acc || (l2 > 0 && l2 == acc)) && (count + 1 >= select_min) && (count + 1 <= select_max))
return true;
++index;
......@@ -1361,9 +1366,8 @@ bool ClientField::check_sel_sum_trib_s(const std::set<ClientCard*>& left, int in
check_sel_sum_trib_t(left, acc);
return acc >= select_min && acc <= select_max;
}
int l = selected_cards[index]->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params(selected_cards[index]->opParam, l1, l2);
bool res1 = false, res2 = false;
res1 = check_sel_sum_trib_s(left, index + 1, acc + l1);
if(l2 > 0)
......@@ -1376,9 +1380,8 @@ void ClientField::check_sel_sum_trib_t(const std::set<ClientCard*>& left, int ac
continue;
std::set<ClientCard*> testlist(left);
testlist.erase(*sit);
int l = (*sit)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params((*sit)->opParam, l1, l2);
if(check_sum_trib(testlist.begin(), testlist.end(), acc + l1)
|| (l2 > 0 && check_sum_trib(testlist.begin(), testlist.end(), acc + l2))) {
selectsum_cards.insert(*sit);
......@@ -1390,9 +1393,8 @@ bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, st
return true;
if(acc > select_max || index == end)
return false;
int l = (*index)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
int l1, l2;
get_sum_params((*index)->opParam, l1, l2);
if((acc + l1 >= select_min && acc + l1 <= select_max) || (acc + l2 >= select_min && acc + l2 <= select_max))
return true;
++index;
......
......@@ -119,6 +119,7 @@ public:
bool ShowSelectSum(bool panelmode);
bool CheckSelectSum();
bool CheckSelectTribute();
void get_sum_params(unsigned int opParam, int& op1, int& op2);
bool check_min(const std::set<ClientCard*>& left, std::set<ClientCard*>::const_iterator index, int min, int max);
bool check_sel_sum_s(const std::set<ClientCard*>& left, int index, int acc);
void check_sel_sum_t(const std::set<ClientCard*>& left, int acc);
......
......@@ -118,6 +118,15 @@ void DuelClient::ClientRead(bufferevent* bev, void* ctx) {
void DuelClient::ClientEvent(bufferevent* bev, short events, void* ctx) {
if (events & BEV_EVENT_CONNECTED) {
bool create_game = (intptr_t)ctx;
if(!create_game) {
uint16_t hostname_buf[LEN_HOSTNAME];
auto hostname_len = BufferIO::CopyCharArray(mainGame->ebJoinHost->getText(), hostname_buf);
auto hostname_msglen = (hostname_len + 1) * sizeof(uint16_t);
char buf[LEN_HOSTNAME * sizeof(uint16_t) + sizeof(uint32_t)];
memset(buf, 0, sizeof(uint32_t)); // real_ip
memcpy(buf + sizeof(uint32_t), hostname_buf, hostname_msglen);
SendBufferToServer(CTOS_EXTERNAL_ADDRESS, buf, hostname_msglen + sizeof(uint32_t));
}
CTOS_PlayerInfo cspi;
BufferIO::CopyCharArray(mainGame->ebNickName->getText(), cspi.name);
SendPacketToServer(CTOS_PLAYER_INFO, cspi);
......@@ -1325,7 +1334,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
}
mainGame->dField.activatable_cards.push_back(pcard);
mainGame->dField.activatable_descs.push_back(std::make_pair(desc, flag));
if(flag == EDESC_OPERATION) {
if(flag & EDESC_OPERATION) {
pcard->chain_code = code;
mainGame->dField.conti_cards.push_back(pcard);
mainGame->dField.conti_act = true;
......@@ -1457,7 +1466,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
}
mainGame->dField.activatable_cards.push_back(pcard);
mainGame->dField.activatable_descs.push_back(std::make_pair(desc, flag));
if(flag == EDESC_OPERATION) {
if(flag & EDESC_OPERATION) {
pcard->chain_code = code;
mainGame->dField.conti_cards.push_back(pcard);
mainGame->dField.conti_act = true;
......@@ -1705,7 +1714,6 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
/*int selecting_player = */BufferIO::ReadUInt8(pbuf);
int count = BufferIO::ReadUInt8(pbuf);
int specount = BufferIO::ReadUInt8(pbuf);
int forced = BufferIO::ReadUInt8(pbuf);
/*int hint0 = */BufferIO::ReadInt32(pbuf);
/*int hint1 = */BufferIO::ReadInt32(pbuf);
int c, s, ss, desc;
......@@ -1714,12 +1722,14 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
bool panelmode = false;
bool conti_exist = false;
bool select_trigger = (specount == 0x7f);
mainGame->dField.chain_forced = (forced != 0);
mainGame->dField.chain_forced = false;
mainGame->dField.activatable_cards.clear();
mainGame->dField.activatable_descs.clear();
mainGame->dField.conti_cards.clear();
for (int i = 0; i < count; ++i) {
int flag = BufferIO::ReadUInt8(pbuf);
int forced = BufferIO::ReadUInt8(pbuf);
flag |= forced << 8;
code = BufferIO::ReadInt32(pbuf);
c = mainGame->LocalPlayer(BufferIO::ReadUInt8(pbuf));
l = BufferIO::ReadUInt8(pbuf);
......@@ -1730,14 +1740,17 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
mainGame->dField.activatable_cards.push_back(pcard);
mainGame->dField.activatable_descs.push_back(std::make_pair(desc, flag));
pcard->is_selected = false;
if(flag == EDESC_OPERATION) {
if(forced) {
mainGame->dField.chain_forced = true;
}
if(flag & EDESC_OPERATION) {
pcard->chain_code = code;
mainGame->dField.conti_cards.push_back(pcard);
mainGame->dField.conti_act = true;
conti_exist = true;
} else {
pcard->is_selectable = true;
if(flag == EDESC_RESET)
if(flag & EDESC_RESET)
pcard->cmdFlag |= COMMAND_RESET;
else
pcard->cmdFlag |= COMMAND_ACTIVATE;
......@@ -1754,7 +1767,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
panelmode = true;
}
}
if(!select_trigger && !forced && (mainGame->ignore_chain || ((count == 0 || specount == 0) && !mainGame->always_chain)) && (count == 0 || !mainGame->chain_when_avail)) {
if(!select_trigger && !mainGame->dField.chain_forced && (mainGame->ignore_chain || ((count == 0 || specount == 0) && !mainGame->always_chain)) && (count == 0 || !mainGame->chain_when_avail)) {
SetResponseI(-1);
mainGame->dField.ClearChainSelect();
if(mainGame->chkWaitChain->isChecked() && !mainGame->ignore_chain) {
......@@ -1763,8 +1776,14 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
DuelClient::SendResponse();
return true;
}
if(mainGame->chkAutoChain->isChecked() && forced && !(mainGame->always_chain || mainGame->chain_when_avail)) {
SetResponseI(0);
if(mainGame->chkAutoChain->isChecked() && mainGame->dField.chain_forced && !(mainGame->always_chain || mainGame->chain_when_avail)) {
for(size_t i = 0; i < mainGame->dField.activatable_descs.size();++i) {
auto it = mainGame->dField.activatable_descs[i];
if(it.second >> 8) {
SetResponseI((int)i);
break;
}
}
mainGame->dField.ClearChainSelect();
DuelClient::SendResponse();
return true;
......@@ -1783,7 +1802,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
mainGame->dField.selectable_cards.erase(eit, mainGame->dField.selectable_cards.end());
mainGame->dField.ShowChainCard();
} else {
if(!forced) {
if(!mainGame->dField.chain_forced) {
if(count == 0)
myswprintf(textBuffer, L"%ls\n%ls", dataManager.GetSysString(201), dataManager.GetSysString(202));
else if(select_trigger)
......@@ -2145,6 +2164,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
}
case MSG_CONFIRM_CARDS: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadUInt8(pbuf));
int skip_panel = BufferIO::ReadUInt8(pbuf);
int count = BufferIO::ReadUInt8(pbuf);
int c, s;
unsigned int code, l;
......@@ -2231,7 +2251,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
}
mainGame->WaitFrameSignal(5);
}
if (panel_confirm.size() && mainGame->dInfo.player_type != 7) {
if (!skip_panel && panel_confirm.size() && mainGame->dInfo.player_type != 7) {
std::sort(panel_confirm.begin(), panel_confirm.end(), ClientCard::client_card_sort);
mainGame->gMutex.lock();
mainGame->dField.selectable_cards = panel_confirm;
......
......@@ -375,9 +375,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
select_options_index.clear();
for (size_t i = 0; i < activatable_cards.size(); ++i) {
if (activatable_cards[i] == menu_card) {
if(activatable_descs[i].second == EDESC_OPERATION)
if(activatable_descs[i].second & EDESC_OPERATION)
continue;
else if(activatable_descs[i].second == EDESC_RESET) {
else if(activatable_descs[i].second & EDESC_RESET) {
if(id == BUTTON_CMD_ACTIVATE) continue;
} else {
if(id == BUTTON_CMD_RESET) continue;
......@@ -658,7 +658,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
select_options_index.clear();
for (size_t i = 0; i < activatable_cards.size(); ++i) {
if (activatable_cards[i] == command_card) {
if(activatable_descs[i].second == EDESC_OPERATION) {
if(activatable_descs[i].second & EDESC_OPERATION) {
if(list_command == COMMAND_ACTIVATE) continue;
} else {
if(list_command == COMMAND_OPERATION) continue;
......
......@@ -28,7 +28,7 @@ namespace irr {
#endif //YGOPRO_SERVER_MODE
#include <thread>
const unsigned short PRO_VERSION = 0x1361;
const unsigned short PRO_VERSION = 0x1362;
namespace ygo {
......
......@@ -234,8 +234,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
case BUTTON_LOAD_REPLAY: {
int start_turn = 1;
if(open_file) {
ReplayMode::cur_replay.OpenReplay(open_file_name);
open_file = false;
if (!ReplayMode::cur_replay.OpenReplay(open_file_name)) {
if (exit_on_return)
mainGame->device->closeDevice();
break;
}
} else {
auto selected = mainGame->lstReplayList->getSelected();
if(selected == -1)
......
......@@ -344,6 +344,15 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
BufferIO::CopyCharArray(pkt->name, dp->name);
break;
}
case CTOS_EXTERNAL_ADDRESS: {
// for other server & reverse proxy use only
/*
wchar_t hostname[LEN_HOSTNAME];
uint32_t real_ip = ntohl(BufferIO::ReadInt32(pdata));
BufferIO::CopyCharArray((uint16_t*)pdata, hostname);
*/
break;
}
case CTOS_CREATE_GAME: {
if(dp->game || duel_mode)
return;
......
......@@ -103,6 +103,14 @@ struct CTOS_Kick {
check_trivially_copyable(CTOS_Kick);
static_assert(sizeof(CTOS_Kick) == 1, "size mismatch: CTOS_Kick");
/*
* CTOS_ExternalAddress
* uint32_t real_ip; (IPv4 address, BE, alway 0 in normal client)
* uint16_t hostname[256]; (UTF-16 string)
*/
constexpr int LEN_HOSTNAME = 256;
// STOC
struct STOC_ErrorMsg {
uint8_t msg{};
......@@ -261,6 +269,7 @@ public:
#define CTOS_SURRENDER 0x14 // no data
#define CTOS_TIME_CONFIRM 0x15 // no data
#define CTOS_CHAT 0x16 // uint16_t array
#define CTOS_EXTERNAL_ADDRESS 0x17 // CTOS_ExternalAddress
#define CTOS_HS_TODUELIST 0x20 // no data
#define CTOS_HS_TOOBSERVER 0x21 // no data
#define CTOS_HS_READY 0x22 // no data
......
......@@ -393,7 +393,7 @@ bool ReplayMode::ReplayAnalyze(unsigned char* msg, unsigned int len) {
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadUInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 10 + count * 13;
pbuf += 9 + count * 14;
return ReadReplayResponse();
}
case MSG_SELECT_PLACE:
......@@ -446,6 +446,7 @@ bool ReplayMode::ReplayAnalyze(unsigned char* msg, unsigned int len) {
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadUInt8(pbuf);
pbuf += 1;
count = BufferIO::ReadUInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
......
......@@ -935,7 +935,7 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadUInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 10 + count * 13;
pbuf += 9 + count * 14;
WaitforResponse(player);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
......@@ -1012,6 +1012,7 @@ int SingleDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadUInt8(pbuf);
pbuf += 1;
count = BufferIO::ReadUInt8(pbuf);
if(pbuf[5] != LOCATION_DECK) {
pbuf += count * 7;
......
......@@ -301,7 +301,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) {
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadUInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 10 + count * 13;
pbuf += 9 + count * 14;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
......@@ -378,6 +378,7 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) {
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadUInt8(pbuf);
pbuf += 1;
count = BufferIO::ReadUInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
......
......@@ -877,7 +877,7 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
case MSG_SELECT_CHAIN: {
player = BufferIO::ReadUInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 10 + count * 13;
pbuf += 9 + count * 14;
WaitforResponse(player);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
......@@ -958,6 +958,7 @@ int TagDuel::Analyze(unsigned char* msgbuffer, unsigned int len) {
}
case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadUInt8(pbuf);
pbuf += 1;
count = BufferIO::ReadUInt8(pbuf);
if(pbuf[5] != LOCATION_DECK) {
pbuf += count * 7;
......
Subproject commit 42c507076905ebd0ed88ca8816880573a7b82ff5
Subproject commit 16c1bc322fc5a012796d880f1f9284808e6aca7a
1 ICON "ygopro.ico"
1 VERSIONINFO
FILEVERSION 1, 0, 36, 1
PRODUCTVERSION 1, 0, 36, 1
FILEVERSION 1, 0, 36, 2
PRODUCTVERSION 1, 0, 36, 2
FILEOS 0x4
FILETYPE 0x1
......@@ -16,8 +16,8 @@ VALUE "InternalName", "YGOPro Server Mode"
VALUE "LegalCopyright", "Copyright (C) 2025 Fluorohydride"
VALUE "OriginalFilename", "YGOPro.exe"
VALUE "ProductName", "YGOPro Server Mode"
VALUE "FileVersion", "1.036.1"
VALUE "ProductVersion", "1.036.1"
VALUE "FileVersion", "1.036.2"
VALUE "ProductVersion", "1.036.2"
END
END
BLOCK "VarFileInfo"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment