summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/chat.c75
-rw-r--r--src/map/chat.h2
-rw-r--r--src/map/clif.c153
-rw-r--r--src/map/clif.h6
-rw-r--r--src/map/map.h6
-rw-r--r--src/map/unit.c2
6 files changed, 135 insertions, 109 deletions
diff --git a/src/map/chat.c b/src/map/chat.c
index 1f8166871..0a2b18d37 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -32,7 +32,7 @@ static struct chat_data* chat_createchat(struct block_list* bl, const char* titl
safestrncpy(cd->pass, pass, sizeof(cd->pass));
cd->pub = pub;
cd->users = 0;
- cd->limit = limit;
+ cd->limit = min(limit, ARRAYSIZE(cd->usersd));
cd->trigger = trigger;
memset(cd->usersd, 0, sizeof(cd->usersd));
cd->owner = bl;
@@ -45,7 +45,8 @@ static struct chat_data* chat_createchat(struct block_list* bl, const char* titl
cd->bl.next = cd->bl.prev = NULL;
cd->bl.id = map_addobject(&cd->bl);
- if( cd->bl.id == 0 ) {
+ if( cd->bl.id == 0 )
+ {
aFree(cd);
cd = NULL;
}
@@ -61,23 +62,27 @@ int chat_createpcchat(struct map_session_data* sd, const char* title, const char
struct chat_data* cd;
nullpo_retr(0, sd);
- if (sd->chatID)
+ if( sd->chatID )
return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex]
- if (map[sd->bl.m].flag.nochat) {
- clif_displaymessage (sd->fd, msg_txt(281));
+ if( map[sd->bl.m].flag.nochat )
+ {
+ clif_displaymessage(sd->fd, msg_txt(281));
return 0; //Can't create chatrooms on this map.
}
+
pc_stop_walking(sd,1);
cd = chat_createchat(&sd->bl, title, pass, limit, pub, 0, "");
- if (cd) {
+ if( cd )
+ {
cd->users = 1;
cd->usersd[0] = sd;
pc_setchatid(sd,cd->bl.id);
clif_createchat(sd,0);
clif_dispchat(cd,0);
- } else
+ }
+ else
clif_createchat(sd,1);
return 0;
@@ -93,11 +98,14 @@ int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass)
nullpo_retr(0, sd);
cd = (struct chat_data*)map_id2bl(chatid);
- if (cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->vender_id || sd->chatID || cd->users >= cd->limit) {
+ if( cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->vender_id || sd->chatID || cd->users >= cd->limit )
+ {
clif_joinchatfail(sd,0);
return 0;
}
- if (!cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !(battle_config.gm_join_chat && pc_isGM(sd) >= battle_config.gm_join_chat)) {
+
+ if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !(battle_config.gm_join_chat && pc_isGM(sd) >= battle_config.gm_join_chat) )
+ {
clif_joinchatfail(sd,1);
return 0;
}
@@ -121,7 +129,7 @@ int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass)
/*==========================================
* leave a chatroom
*------------------------------------------*/
-int chat_leavechat(struct map_session_data* sd)
+int chat_leavechat(struct map_session_data* sd, bool kicked)
{
struct chat_data* cd;
int i;
@@ -138,23 +146,23 @@ int chat_leavechat(struct map_session_data* sd)
ARR_FIND( 0, cd->users, i, cd->usersd[i] == sd );
if ( i == cd->users )
- {// Not found in the chatroom?
+ { // Not found in the chatroom?
pc_setchatid(sd, 0);
return -1;
}
leavechar = i;
- clif_leavechat(cd, sd);
+ clif_leavechat(cd, sd, kicked);
for( i = leavechar; i < cd->users; i++ )
- cd->usersd[i] = cd->usersd[i + 1];
+ cd->usersd[i] = cd->usersd[i+1];
pc_setchatid(sd, 0);
cd->users--;
if( cd->users == 0 && cd->owner->type == BL_PC )
- {// Delete empty chatroom
+ { // Delete empty chatroom
clif_clearchat(cd, 0);
map_delobject(cd->bl.id);
return 1;
@@ -187,29 +195,28 @@ int chat_changechatowner(struct map_session_data* sd, const char* nextownername)
{
struct chat_data* cd;
struct map_session_data* tmpsd;
- int i, nextowner;
+ int i;
nullpo_retr(1, sd);
cd = (struct chat_data*)map_id2bl(sd->chatID);
- if (cd == NULL || (struct block_list*) sd != cd->owner)
+ if( cd == NULL || (struct block_list*) sd != cd->owner )
return 1;
ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 );
- if (i == cd->users)
+ if( i == cd->users )
return -1; // name not found
// erase temporarily
clif_clearchat(cd,0);
// set new owner
- nextowner = i;
- cd->owner = (struct block_list*) cd->usersd[nextowner];
- clif_changechatowner(cd,cd->usersd[nextowner]);
+ cd->owner = (struct block_list*) cd->usersd[i];
+ clif_changechatowner(cd,cd->usersd[i]);
- // change the owner's position (placing him to 0)
- tmpsd = cd->usersd[nextowner];
- cd->usersd[nextowner] = cd->usersd[0];
+ // swap the old and new owners' positions
+ tmpsd = cd->usersd[i];
+ cd->usersd[i] = cd->usersd[0];
cd->usersd[0] = tmpsd;
// set the new chatroom position
@@ -233,13 +240,13 @@ int chat_changechatstatus(struct map_session_data* sd, const char* title, const
nullpo_retr(1, sd);
- cd=(struct chat_data*)map_id2bl(sd->chatID);
- if(cd==NULL || (struct block_list *)sd != cd->owner)
+ cd = (struct chat_data*)map_id2bl(sd->chatID);
+ if( cd==NULL || (struct block_list *)sd != cd->owner )
return 1;
safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE);
safestrncpy(cd->pass, pass, CHATROOM_PASS_SIZE);
- cd->limit = limit;
+ cd->limit = min(limit, ARRAYSIZE(cd->usersd));
cd->pub = pub;
clif_changechatstatus(cd);
@@ -260,17 +267,17 @@ int chat_kickchat(struct map_session_data* sd, const char* kickusername)
cd = (struct chat_data *)map_id2bl(sd->chatID);
- if (!cd)
+ if( !cd )
return -1;
ARR_FIND( 0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0 );
- if (i == cd->users)
+ if( i == cd->users )
return -1;
- if (battle_config.gm_kick_chat && pc_isGM(cd->usersd[i]) >= battle_config.gm_kick_chat)
+ if( battle_config.gm_kick_chat && pc_isGM(cd->usersd[i]) >= battle_config.gm_kick_chat )
return 0; //gm kick protection [Valaris]
- chat_leavechat(cd->usersd[i]);
+ chat_leavechat(cd->usersd[i],1);
return 0;
}
@@ -281,7 +288,7 @@ int chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool p
nullpo_retr(0, nd);
cd = chat_createchat(&nd->bl, title, "", limit, pub, trigger, ev);
- if (cd)
+ if( cd )
{
nd->chat_id = cd->bl.id;
clif_dispchat(cd,0);
@@ -296,7 +303,7 @@ int chat_deletenpcchat(struct npc_data* nd)
struct chat_data *cd;
nullpo_retr(0, nd);
- nullpo_retr(0, cd=(struct chat_data*)map_id2bl(nd->chat_id));
+ nullpo_retr(0, cd = (struct chat_data*)map_id2bl(nd->chat_id));
chat_npckickall(cd);
clif_clearchat(cd, 0);
@@ -338,13 +345,13 @@ int chat_disableevent(struct chat_data* cd)
return 0;
}
-/// Kicks all the users for the chat room.
+/// Kicks all the users from the chat room.
int chat_npckickall(struct chat_data* cd)
{
nullpo_retr(0, cd);
while( cd->users > 0 )
- chat_leavechat(cd->usersd[cd->users-1]);
+ chat_leavechat(cd->usersd[cd->users-1],0);
return 0;
}
diff --git a/src/map/chat.h b/src/map/chat.h
index aac356584..d7bfb3f50 100644
--- a/src/map/chat.h
+++ b/src/map/chat.h
@@ -10,7 +10,7 @@ struct chat_data;
int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub);
int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass);
-int chat_leavechat(struct map_session_data* sd);
+int chat_leavechat(struct map_session_data* sd, bool kicked);
int chat_changechatowner(struct map_session_data* sd, const char* nextownername);
int chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub);
int chat_kickchat(struct map_session_data* sd, const char* kickusername);
diff --git a/src/map/clif.c b/src/map/clif.c
index 9a3e5e7d9..8af8de5d8 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -3156,43 +3156,50 @@ int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok)
}
/*==========================================
- *
+ * Inform client whether chatroom creation was successful or not
+ * R 00d6 <fail>.B
*------------------------------------------*/
-int clif_createchat(struct map_session_data *sd,int fail)
+void clif_createchat(struct map_session_data* sd, int fail)
{
int fd;
- nullpo_retr(0, sd);
+ nullpo_retv(sd);
- fd=sd->fd;
+ fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xd6));
- WFIFOW(fd,0)=0xd6;
- WFIFOB(fd,2)=fail;
+ WFIFOW(fd,0) = 0xd6;
+ WFIFOB(fd,2) = fail;
WFIFOSET(fd,packet_len(0xd6));
-
- return 0;
}
/*==========================================
- *
+ * Display a chat above the owner
+ * R 00d7 <len>.w <owner ID>.l <chat ID>.l <limit>.w <users>.w <type>.B <title>.?B
*------------------------------------------*/
int clif_dispchat(struct chat_data* cd, int fd)
{
- unsigned char buf[128]; // 最大title(60バイト)+17
+ unsigned char buf[128];
+ uint8 type;
- if(cd==NULL || cd->owner==NULL)
+ if( cd == NULL || cd->owner == NULL )
return 1;
- WBUFW(buf,0)=0xd7;
- WBUFW(buf,2)=strlen((const char*)cd->title)+17;
- WBUFL(buf,4)=cd->owner->id;
- WBUFL(buf,8)=cd->bl.id;
- WBUFW(buf,12)=cd->limit;
- WBUFW(buf,14)=cd->users;
- WBUFB(buf,16)=cd->pub;
- strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
- if(fd){
- WFIFOHEAD(fd, WBUFW(buf,2));
+ // type - 0: private, 1: public, 2: npc, 3: non-clickable
+ type = (cd->owner->type == BL_PC ) ? (cd->pub) ? 1 : 0
+ : (cd->owner->type == BL_NPC) ? (cd->limit) ? 2 : 3
+ : 1;
+
+ WBUFW(buf, 0) = 0xd7;
+ WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFL(buf, 4) = cd->owner->id;
+ WBUFL(buf, 8) = cd->bl.id;
+ WBUFW(buf,12) = cd->limit;
+ WBUFW(buf,14) = cd->users;
+ WBUFB(buf,16) = type;
+ strncpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
+
+ if( fd ) {
+ WFIFOHEAD(fd,WBUFW(buf,2));
memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
WFIFOSET(fd,WBUFW(buf,2));
} else {
@@ -3203,24 +3210,25 @@ int clif_dispchat(struct chat_data* cd, int fd)
}
/*==========================================
- * chatの状態変更成功
- * 外部の人用と命令コード(d7->df)が違うだけ
+ * Chatroom properties adjustment
+ * R 00df <len>.w <owner ID>.l <chat ID>.l <limit>.w <users>.w <pub>.B <title>.?B
*------------------------------------------*/
-int clif_changechatstatus(struct chat_data *cd)
+int clif_changechatstatus(struct chat_data* cd)
{
- unsigned char buf[128]; // 最大title(60バイト)+17
+ unsigned char buf[128];
- if(cd==NULL || cd->usersd[0]==NULL)
+ if( cd == NULL || cd->usersd[0] == NULL )
return 1;
- WBUFW(buf,0)=0xdf;
- WBUFW(buf,2)=strlen((char*)cd->title)+17;
- WBUFL(buf,4)=cd->usersd[0]->bl.id;
- WBUFL(buf,8)=cd->bl.id;
- WBUFW(buf,12)=cd->limit;
- WBUFW(buf,14)=cd->users;
- WBUFB(buf,16)=cd->pub;
- strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
+ WBUFW(buf, 0) = 0xdf;
+ WBUFW(buf, 2) = 17 + strlen(cd->title);
+ WBUFL(buf, 4) = cd->usersd[0]->bl.id;
+ WBUFL(buf, 8) = cd->bl.id;
+ WBUFW(buf,12) = cd->limit;
+ WBUFW(buf,14) = cd->users;
+ WBUFB(buf,16) = cd->pub;
+ strncpy((char*)WBUFP(buf,17), cd->title, strlen(cd->title)); // not zero-terminated
+
clif_send(buf,WBUFW(buf,2),&cd->usersd[0]->bl,CHAT);
return 0;
@@ -3235,9 +3243,9 @@ int clif_clearchat(struct chat_data *cd,int fd)
nullpo_retr(0, cd);
- WBUFW(buf,0)=0xd8;
- WBUFL(buf,2)=cd->bl.id;
- if(fd){
+ WBUFW(buf,0) = 0xd8;
+ WBUFL(buf,2) = cd->bl.id;
+ if( fd ) {
WFIFOHEAD(fd,packet_len(0xd8));
memcpy(WFIFOP(fd,0),buf,packet_len(0xd8));
WFIFOSET(fd,packet_len(0xd8));
@@ -3257,11 +3265,11 @@ int clif_joinchatfail(struct map_session_data *sd,int fail)
nullpo_retr(0, sd);
- fd=sd->fd;
+ fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xda));
- WFIFOW(fd,0)=0xda;
- WFIFOB(fd,2)=fail;
+ WFIFOW(fd,0) = 0xda;
+ WFIFOB(fd,2) = fail;
WFIFOSET(fd,packet_len(0xda));
return 0;
@@ -3313,45 +3321,48 @@ int clif_addchat(struct chat_data* cd,struct map_session_data *sd)
}
/*==========================================
- *
+ * Announce the new owner
+ * R 00e1 <index>.l <nick>.24B
*------------------------------------------*/
-int clif_changechatowner(struct chat_data* cd, struct map_session_data* sd)
+void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd)
{
unsigned char buf[64];
- nullpo_retr(0, sd);
- nullpo_retr(0, cd);
+ nullpo_retv(sd);
+ nullpo_retv(cd);
+
+ //FIXME: this announces a swap between positions 0 and 1 (probably not what we want) [ultramage]
+ //FIXME: aegis sends obviously incorrect packets; need to figure out what to send to display it correctly :X
+ //TODO: is it just owner swap, or can it do general-purpose reordering?
WBUFW(buf, 0) = 0xe1;
WBUFL(buf, 2) = 1;
memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,NAME_LENGTH);
+
WBUFW(buf,30) = 0xe1;
WBUFL(buf,32) = 0;
memcpy(WBUFP(buf,36),sd->status.name,NAME_LENGTH);
clif_send(buf,packet_len(0xe1)*2,&sd->bl,CHAT);
-
- return 0;
}
/*==========================================
- *
+ * Notify about user leaving the chatroom
+ * R 00dd <index>.w <nick>.24B <flag>.B
*------------------------------------------*/
-int clif_leavechat(struct chat_data* cd,struct map_session_data *sd)
+void clif_leavechat(struct chat_data* cd, struct map_session_data* sd, bool flag)
{
unsigned char buf[32];
- nullpo_retr(0, sd);
- nullpo_retr(0, cd);
+ nullpo_retv(sd);
+ nullpo_retv(cd);
WBUFW(buf, 0) = 0xdd;
WBUFW(buf, 2) = cd->users-1;
memcpy(WBUFP(buf,4),sd->status.name,NAME_LENGTH);
- WBUFB(buf,28) = 0;
+ WBUFB(buf,28) = flag; // 0: left, 1: was kicked
clif_send(buf,packet_len(0xdd),&sd->bl,CHAT);
-
- return 0;
}
/*==========================================
@@ -9215,13 +9226,14 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
}
/*==========================================
- *
+ * Chatroom creation request
+ * S 00d5 <len>.w <limit>.w <pub>.B <passwd>.8B <title>.?B
*------------------------------------------*/
void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
{
int len = RFIFOW(fd,2)-15;
int limit = RFIFOW(fd,4);
- bool public = (bool)RFIFOB(fd,6);
+ bool pub = (RFIFOB(fd,6) != 0);
const char* password = (char*)RFIFOP(fd,7); //not zero-terminated
const char* title = (char*)RFIFOP(fd,15); // not zero-terminated
char s_title[CHATROOM_TITLE_SIZE];
@@ -9237,26 +9249,31 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE));
safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
- chat_createpcchat(sd, s_title, s_password, limit, public);
+ chat_createpcchat(sd, s_title, s_password, limit, pub);
}
/*==========================================
- *
+ * Chatroom join request
+ * S 00d9 <chat ID>.l <passwd>.8B
*------------------------------------------*/
-void clif_parse_ChatAddMember(int fd,struct map_session_data *sd)
+void clif_parse_ChatAddMember(int fd, struct map_session_data* sd)
{
- chat_joinchat(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
+ int chatid = RFIFOL(fd,2);
+ const char* password = (char*)RFIFOP(fd,6); // not zero-terminated
+
+ chat_joinchat(sd,chatid,password);
}
/*==========================================
+ * Chatroom properties adjustment request
* S 00de <len>.w <limit>.w <pub>.B <passwd>.8B <title>.?B
*------------------------------------------*/
void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd)
{
int len = RFIFOW(fd,2)-15;
int limit = RFIFOW(fd,4);
- bool public = (bool)RFIFOB(fd,6);
- const char* password = (char*)RFIFOP(fd,7); //not zero-terminated
+ bool pub = (RFIFOB(fd,6) != 0);
+ const char* password = (char*)RFIFOP(fd,7); // not zero-terminated
const char* title = (char*)RFIFOP(fd,15); // not zero-terminated
char s_title[CHATROOM_TITLE_SIZE];
@@ -9264,14 +9281,15 @@ void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd)
safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE));
safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
- chat_changechatstatus(sd, s_title, s_password, limit, public);
+ chat_changechatstatus(sd, s_title, s_password, limit, pub);
}
/*==========================================
- *
+ * S 00e0 ?.l <nick>.24B
*------------------------------------------*/
-void clif_parse_ChangeChatOwner(int fd,struct map_session_data *sd)
+void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd)
{
+ //TODO: the first argument seems to be the destination position (always 0) [ultramage]
chat_changechatowner(sd,(char*)RFIFOP(fd,6));
}
@@ -9284,11 +9302,12 @@ void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
}
/*==========================================
- *
+ * Request to leave the current chatroom
+ * S 00e3
*------------------------------------------*/
-void clif_parse_ChatLeave(int fd,struct map_session_data *sd)
+void clif_parse_ChatLeave(int fd, struct map_session_data* sd)
{
- chat_leavechat(sd);
+ chat_leavechat(sd,0);
}
//Handles notifying asker and rejecter of what has just ocurred.
diff --git a/src/map/clif.h b/src/map/clif.h
index dd0fff340..54a643b85 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -138,14 +138,14 @@ int clif_changeoption(struct block_list*); // area
int clif_changeoption2(struct block_list*); // area
int clif_useitemack(struct map_session_data*,int,int,int); // self
void clif_GlobalMessage(struct block_list* bl, const char* message);
-int clif_createchat(struct map_session_data*,int); // self
+void clif_createchat(struct map_session_data* sd, int fail); // self
int clif_dispchat(struct chat_data*,int); // area or fd
int clif_joinchatfail(struct map_session_data*,int); // self
int clif_joinchatok(struct map_session_data*,struct chat_data*); // self
int clif_addchat(struct chat_data*,struct map_session_data*); // chat
-int clif_changechatowner(struct chat_data*,struct map_session_data*); // chat
+void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd); // chat
int clif_clearchat(struct chat_data*,int); // area or fd
-int clif_leavechat(struct chat_data*,struct map_session_data*); // chat
+void clif_leavechat(struct chat_data* cd, struct map_session_data* sd, bool flag); // chat
int clif_changechatstatus(struct chat_data*); // chat
int clif_refresh(struct map_session_data*); // self
diff --git a/src/map/map.h b/src/map/map.h
index c7a6556c5..5a8c55315 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1140,9 +1140,9 @@ struct chat_data {
char title[CHATROOM_TITLE_SIZE]; // room title
char pass[CHATROOM_PASS_SIZE]; // password
bool pub; // private/public flag
- unsigned char users; // current users
- unsigned char limit; // join limit
- unsigned char trigger; // number of users needed to trigger event
+ uint8 users; // current user count
+ uint8 limit; // join limit
+ uint8 trigger; // number of users needed to trigger event
struct map_session_data* usersd[20];
struct block_list* owner;
char npc_event[50];
diff --git a/src/map/unit.c b/src/map/unit.c
index ba3f9926a..05175a991 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1674,7 +1674,7 @@ int unit_remove_map(struct block_list *bl, int clrtype)
//Leave/reject all invitations.
if(sd->chatID)
- chat_leavechat(sd);
+ chat_leavechat(sd,0);
if(sd->trade_partner)
trade_tradecancel(sd);
if(sd->vender_id)