Skip to content

Commit 216c752

Browse files
Merge pull request #3304 from guilherme-gm/fix-account-sync
Fix server sync reading and wrong disconnection from API Server
2 parents 5f7eaa4 + 4306daa commit 216c752

File tree

4 files changed

+75
-21
lines changed

4 files changed

+75
-21
lines changed

src/char/char.c

+17-9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "common/HPM.h"
5151
#include "common/apipackets.h"
5252
#include "common/cbasetypes.h"
53+
#include "common/charloginpackets.h"
5354
#include "common/chunked.h"
5455
#include "common/conf.h"
5556
#include "common/console.h"
@@ -5298,10 +5299,11 @@ static int char_send_accounts_tologin_sub(union DBKey key, struct DBData *data,
52985299
{
52995300
struct online_char_data* character = DB->data2ptr(data);
53005301
int* i = va_arg(ap, int*);
5302+
int* accounts = va_arg(ap, int *);
53015303

53025304
nullpo_ret(character);
53035305
if (character->mapserver_connection == OCS_CONNECTED) {
5304-
WFIFOL(chr->login_fd,8+(*i)*4) = character->account_id;
5306+
accounts[*i] = character->account_id;
53055307
(*i)++;
53065308
return 1;
53075309
}
@@ -5310,18 +5312,24 @@ static int char_send_accounts_tologin_sub(union DBKey key, struct DBData *data,
53105312

53115313
static int char_send_accounts_tologin(int tid, int64 tick, int id, intptr_t data)
53125314
{
5313-
if (chr->login_fd > 0 && sockt->session[chr->login_fd])
5314-
{
5315+
if (chr->login_fd > 0 && sockt->session[chr->login_fd] != NULL) {
53155316
// send account list to login server
53165317
int users = chr->online_char_db->size(chr->online_char_db);
53175318
int i = 0;
53185319

5319-
WFIFOHEAD(chr->login_fd,8+users*4);
5320-
WFIFOW(chr->login_fd,0) = 0x272d;
5321-
chr->online_char_db->foreach(chr->online_char_db, chr->send_accounts_tologin_sub, &i, users);
5322-
WFIFOW(chr->login_fd,2) = 8+ i*4;
5323-
WFIFOL(chr->login_fd,4) = i;
5324-
WFIFOSET(chr->login_fd,WFIFOW(chr->login_fd,2));
5320+
struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS *p;
5321+
int len = sizeof(struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS) + sizeof(*p->accounts) * users;
5322+
5323+
WFIFOHEAD(chr->login_fd, len);
5324+
p = WFIFOP(chr->login_fd, 0);
5325+
p->packetType = HEADER_CHARLOGIN_ONLINE_ACCOUNTS;
5326+
5327+
chr->online_char_db->foreach(chr->online_char_db, chr->send_accounts_tologin_sub, &i, p->accounts);
5328+
5329+
p->packetLength = sizeof(struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS) + sizeof(*p->accounts) * i;
5330+
p->list_length = i;
5331+
5332+
WFIFOSET(chr->login_fd, len);
53255333
}
53265334
return 0;
53275335
}

src/common/Makefile.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ COMMON_H = atomic.h cbasetypes.h base62.h conf.h console.h core.h db.h des.h ers
6262
grfio.h hercules.h HPM.h HPMi.h memmgr.h memmgr_inc.h mapindex.h \
6363
md5calc.h mmo.h mutex.h nullpo.h packets.h packets_len.h packets_struct.h random.h \
6464
showmsg.h socket.h spinlock.h sql.h strlib.h sysinfo.h thread.h \
65-
timer.h utils.h winapi.h api.h charmappackets.h mapcharpackets.h \
65+
timer.h utils.h winapi.h api.h charloginpackets.h charmappackets.h mapcharpackets.h \
6666
chunked/rfifo.h chunked/wfifo.h config/defc.h config/emblems.h config/undefc.h \
6767
../plugins/HPMHooking.h
6868
COMMON_PH =

src/common/charloginpackets.h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* This file is part of Hercules.
3+
* http://herc.ws - http://github.com/HerculesWS/Hercules
4+
*
5+
* Copyright (C) 2012-2024 Hercules Dev Team
6+
* Copyright (C) Athena Dev Teams
7+
*
8+
* Hercules is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
*/
21+
#ifndef COMMON_CHARLOGINPACKETS_H
22+
#define COMMON_CHARLOGINPACKETS_H
23+
24+
// Packets sent by Char-Server to Login-Server
25+
26+
#include "common/hercules.h"
27+
28+
/* Packets Structs */
29+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
30+
#pragma pack(push, 1)
31+
#endif // not NetBSD < 6 / Solaris
32+
33+
struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS {
34+
int16 packetType;
35+
uint16 packetLength;
36+
uint32 list_length;
37+
int accounts[];
38+
} __attribute__((packed));
39+
DEFINE_PACKET_ID(CHARLOGIN_ONLINE_ACCOUNTS, 0x272d)
40+
41+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
42+
#pragma pack(pop)
43+
#endif // not NetBSD < 6 / Solaris
44+
45+
#endif /* COMMON_CHARLOGINPACKETS_H */

src/login/login.c

+12-11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "common/HPM.h"
3333
#include "common/apipackets.h"
3434
#include "common/cbasetypes.h"
35+
#include "common/charloginpackets.h"
3536
#include "common/conf.h"
3637
#include "common/core.h"
3738
#include "common/db.h"
@@ -675,17 +676,17 @@ static void login_fromchar_parse_account_offline(int fd)
675676

676677
static void login_fromchar_parse_online_accounts(int fd, int id)
677678
{
678-
uint32 i, users;
679679
login->online_db->foreach(login->online_db, login->online_db_setoffline, id); //Set all chars from this char-server offline first
680-
users = RFIFOW(fd,4);
681-
for (i = 0; i < users; i++) {
682-
int aid = RFIFOL(fd,6+i*4);
683-
struct online_login_data *p = idb_ensure(login->online_db, aid, login->create_online_user);
684-
p->char_server = id;
685-
if (p->waiting_disconnect != INVALID_TIMER)
686-
{
687-
timer->delete(p->waiting_disconnect, login->waiting_disconnect_timer);
688-
p->waiting_disconnect = INVALID_TIMER;
680+
681+
const struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS *p = RFIFOP(fd, 0);
682+
for (uint32 i = 0; i < p->list_length; i++) {
683+
int aid = p->accounts[i];
684+
struct online_login_data *login_data = idb_ensure(login->online_db, aid, login->create_online_user);
685+
login_data->char_server = id;
686+
687+
if (login_data->waiting_disconnect != INVALID_TIMER) {
688+
timer->delete(login_data->waiting_disconnect, login->waiting_disconnect_timer);
689+
login_data->waiting_disconnect = INVALID_TIMER;
689690
}
690691
}
691692
}
@@ -950,7 +951,7 @@ static int login_parse_fromchar(int fd)
950951
login->fromchar_parse_account_offline(fd);
951952
break;
952953

953-
case 0x272d: // Receive list of all online accounts. [Skotlex]
954+
case HEADER_CHARLOGIN_ONLINE_ACCOUNTS: // Receive list of all online accounts. [Skotlex]
954955
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
955956
return 0;
956957
{

0 commit comments

Comments
 (0)