summaryrefslogtreecommitdiff
path: root/src/emap/clif.c
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-07-04 22:37:51 +0300
committerAndrei Karas <akaras@inbox.ru>2015-07-04 22:37:51 +0300
commit58b8c8d8cb9f78537495f908887fea9d0a451637 (patch)
tree74438cc91f5c5a6a7a953c98aa52106eb88b250f /src/emap/clif.c
parent857c86d93ebd68e5edbbe14ce26a16a967622822 (diff)
downloadevol-hercules-58b8c8d8cb9f78537495f908887fea9d0a451637.tar.gz
evol-hercules-58b8c8d8cb9f78537495f908887fea9d0a451637.tar.bz2
evol-hercules-58b8c8d8cb9f78537495f908887fea9d0a451637.tar.xz
evol-hercules-58b8c8d8cb9f78537495f908887fea9d0a451637.zip
Rename login/char/map dirs to elogin/echar/emap for avoid conflicts with hercules.
Diffstat (limited to 'src/emap/clif.c')
-rw-r--r--src/emap/clif.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/emap/clif.c b/src/emap/clif.c
new file mode 100644
index 0000000..7651f09
--- /dev/null
+++ b/src/emap/clif.c
@@ -0,0 +1,377 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2014 Evol developers
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/HPMi.h"
+#include "common/malloc.h"
+#include "common/mmo.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/cbasetypes.h"
+#include "map/guild.h"
+#include "map/mob.h"
+#include "map/npc.h"
+#include "map/pc.h"
+#include "map/quest.h"
+
+#include "emap/clif.h"
+#include "emap/lang.h"
+#include "emap/send.h"
+#include "emap/data/mapd.h"
+#include "emap/data/session.h"
+#include "emap/struct/mapdext.h"
+#include "emap/struct/sessionext.h"
+
+void eclif_quest_send_list(TBL_PC *sd)
+{
+ if (!sd)
+ {
+ hookStop();
+ return;
+ }
+
+ int fd = sd->fd;
+ int i;
+ int info_len = 15;
+ int len = sd->avail_quests * info_len + 8;
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd, 0) = 0x97a;
+ WFIFOW(fd, 2) = len;
+ WFIFOL(fd, 4) = sd->avail_quests;
+
+ for (i = 0; i < sd->avail_quests; i++ )
+ {
+ struct quest_db *qi = quest->db(sd->quest_log[i].quest_id);
+ if (!qi)
+ continue;
+ WFIFOL(fd, i * info_len + 8) = sd->quest_log[i].quest_id;
+ WFIFOB(fd, i * info_len + 12) = sd->quest_log[i].count[0]; // was state
+ WFIFOL(fd, i * info_len + 13) = sd->quest_log[i].time - qi->time;
+ WFIFOL(fd, i * info_len + 17) = sd->quest_log[i].time;
+ WFIFOW(fd, i * info_len + 21) = 0;
+ }
+
+ WFIFOSET(fd, len);
+ hookStop();
+}
+
+void eclif_quest_add(TBL_PC *sd, struct quest *qd)
+{
+ if (!sd)
+ {
+ hookStop();
+ return;
+ }
+ int fd = sd->fd;
+ struct quest_db *qi = quest->db(qd->quest_id);
+
+ if (!qi)
+ {
+ hookStop();
+ return;
+ }
+
+ WFIFOHEAD(fd, 107);
+ WFIFOW(fd, 0) = 0x2b3;
+ WFIFOL(fd, 2) = qd->quest_id;
+ WFIFOB(fd, 6) = qd->count[0]; // was state;
+ WFIFOB(fd, 7) = qd->time - qi->time;
+ WFIFOL(fd, 11) = qd->time;
+ WFIFOW(fd, 15) = 0;
+ WFIFOSET(fd, 107);
+ hookStop();
+}
+
+void eclif_charnameack(int *fdPtr, struct block_list *bl)
+{
+ if (!bl)
+ {
+ hookStop();
+ return;
+ }
+ if (bl->type == BL_NPC)
+ {
+ int fd = *fdPtr;
+ TBL_PC* sd = (TBL_PC*)session[fd]->session_data;
+ if (!sd)
+ {
+ hookStop();
+ return;
+ }
+ const char *tr = lang_pctrans(((TBL_NPC*)bl)->name, sd);
+ const int trLen = strlen(tr);
+ const int len = 8 + trLen;
+ // if no recipient specified just update nearby clients
+ if (fd == 0)
+ {
+ char *buf;
+ CREATE(buf, char, len);
+ WBUFW(buf, 0) = 0xB01;
+ WBUFW(buf, 2) = len;
+ WBUFL(buf, 4) = bl->id;
+ memcpy(WBUFP(buf, 8), tr, trLen);
+ clif->send(buf, len, bl, AREA);
+ aFree(buf);
+ }
+ else
+ {
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0xB01;
+ WFIFOW(fd, 2) = len;
+ WFIFOL(fd, 4) = bl->id;
+ memcpy(WFIFOP(fd, 8), tr, trLen);
+ WFIFOSET(fd, len);
+ }
+ hookStop();
+ }
+ else if (bl->type == BL_MOB)
+ {
+ struct mob_data *md = (struct mob_data *)bl;
+ if (!md)
+ {
+ hookStop();
+ return;
+ }
+ if (md->guardian_data && md->guardian_data->g)
+ return; // allow default code to work
+ int fd = *fdPtr;
+ TBL_PC* sd = (TBL_PC*)session[fd]->session_data;
+ if (!sd)
+ {
+ hookStop();
+ return;
+ }
+
+ char tmpBuf[25];
+ char *ptr = tmpBuf;
+ int f;
+ memcpy(tmpBuf, md->name, 24);
+ tmpBuf[24] = 0;
+ for (f = 23; f > 1; f --)
+ {
+ if (tmpBuf[f] == ' ')
+ tmpBuf[f] = 0;
+ else
+ break;
+ }
+ for (f = 0; f < 24; f ++)
+ {
+ if (*ptr == ' ')
+ ptr ++;
+ else
+ break;
+ }
+ const char *tr = lang_pctrans(ptr, sd);
+ const int trLen = strlen(tr);
+ const int len = 8 + trLen;
+
+ // if no recipient specified just update nearby clients
+ if (fd == 0)
+ {
+ char *buf;
+ CREATE(buf, char, len);
+ WBUFW(buf, 0) = 0xB01;
+ WBUFW(buf, 2) = len;
+ WBUFL(buf, 4) = bl->id;
+ memcpy(WBUFP(buf, 8), tr, trLen);
+ clif->send(buf, len, bl, AREA);
+ aFree(buf);
+ }
+ else
+ {
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0xB01;
+ WFIFOW(fd, 2) = len;
+ WFIFOL(fd, 4) = bl->id;
+ memcpy(WFIFOP(fd, 8), tr, trLen);
+ WFIFOSET(fd, len);
+ }
+ hookStop();
+ }
+}
+
+#define equipPos(index, field) \
+ equip = sd->equip_index[index]; \
+ if (equip >= 0) \
+ { \
+ item = sd->inventory_data[equip]; \
+ if (item && item->look) \
+ send_changelook(fd, id, field, item->look); \
+ }
+
+static void eclif_send_additional_slots(TBL_PC* sd, TBL_PC* sd2)
+{
+ if (!sd || !sd2)
+ return;
+
+ const int id = sd->bl.id;
+ const int fd = sd2->fd;
+
+ struct item_data *item;
+ short equip;
+ struct MapdExt *data = mapd_get(sd->bl.m);
+ if (!data || data->invisible)
+ return;
+
+ equipPos(EQI_HEAD_LOW, LOOK_HEAD_BOTTOM);
+ equipPos(EQI_HEAD_TOP, LOOK_HEAD_TOP);
+ equipPos(EQI_HEAD_MID, LOOK_HEAD_MID);
+ equipPos(EQI_GARMENT, LOOK_ROBE);
+ equipPos(EQI_SHOES, LOOK_SHOES);
+ equipPos(EQI_COSTUME_TOP, 13);
+ equipPos(EQI_COSTUME_MID, 14);
+ equipPos(EQI_COSTUME_LOW, 15);
+ equipPos(EQI_COSTUME_GARMENT, 16);
+ equipPos(EQI_ARMOR, 17);
+ //skipping SHADOW slots
+}
+
+void eclif_getareachar_unit_post(TBL_PC* sd, struct block_list *bl)
+{
+ if (!bl)
+ return;
+ if (bl->type == BL_PC)
+ {
+ eclif_send_additional_slots(sd, (TBL_PC *)bl);
+ eclif_send_additional_slots((TBL_PC *)bl, sd);
+ }
+}
+
+void eclif_authok_post(TBL_PC *sd)
+{
+ if (!sd)
+ return;
+
+ eclif_send_additional_slots(sd, sd);
+ send_pc_info(&sd->bl, &sd->bl, SELF);
+ struct MapdExt *data = mapd_get(sd->bl.m);
+ int mask = data ? data->mask : 1;
+ send_mapmask(sd->fd, mask);
+}
+
+void eclif_changemap_post(TBL_PC *sd, short *m,
+ int *x __attribute__ ((unused)), int *y __attribute__ ((unused)))
+{
+ if (!sd)
+ return;
+ struct MapdExt *data = mapd_get(*m);
+ int mask = data ? data->mask : 1;
+ send_mapmask(sd->fd, mask);
+}
+
+void eclif_handle_invisible_map(struct block_list *bl, enum send_target target __attribute__ ((unused)))
+{
+ if (!bl || bl->type != BL_PC)
+ return;
+ struct MapdExt *data = mapd_get(bl->m);
+ if (data && data->invisible)
+ hookStop();
+}
+
+void eclif_sendlook(struct block_list *bl,
+ int *id __attribute__ ((unused)),
+ int *type __attribute__ ((unused)),
+ int *val __attribute__ ((unused)),
+ int *val2 __attribute__ ((unused)),
+ enum send_target *target)
+{
+ if (*target == SELF)
+ return;
+ eclif_handle_invisible_map(bl, *target);
+}
+
+bool eclif_send(const void* buf __attribute__ ((unused)),
+ int *len __attribute__ ((unused)),
+ struct block_list* bl,
+ enum send_target *type)
+{
+ if (*type == SELF)
+ return true;
+ eclif_handle_invisible_map(bl, *type);
+ return true;
+}
+
+void eclif_set_unit_idle(struct block_list* bl, TBL_PC *tsd, enum send_target *target)
+{
+ if (tsd && bl && bl->id == tsd->bl.id && *target == SELF)
+ return;
+
+ eclif_handle_invisible_map(bl, *target);
+}
+
+int eclif_send_actual(int *fd, void *buf, int *len)
+{
+ if (*len >= 2)
+ {
+ const int packet = RBUFW (buf, 0);
+ if (packet >= 0xb02 && packet <= 0xb10)
+ {
+ struct SessionExt *data = session_get(*fd);
+ if (!data)
+ return 0;
+ if (data->clientVersion < 3)
+ { // not sending new packets to old clients
+// ShowWarning("skip packet %d\n", packet);
+ hookStop();
+ return 0;
+ }
+ }
+ if (packet >= 0xb03 && packet <= 0xb0a)
+ {
+ struct SessionExt *data = session_get(*fd);
+ if (!data)
+ return 0;
+ if (data->clientVersion < 4)
+ { // not sending new packets to old clients
+// ShowWarning("skip packet %d\n", packet);
+ hookStop();
+ return 0;
+ }
+ }
+ if (packet == 0xb0b)
+ {
+ struct SessionExt *data = session_get(*fd);
+ if (!data)
+ return 0;
+ if (data->clientVersion < 5)
+ { // not sending new packets to old clients
+// ShowWarning("skip packet %d\n", packet);
+ hookStop();
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+void eclif_set_unit_idle_post(struct block_list* bl, TBL_PC *tsd,
+ enum send_target *target)
+{
+ if (!bl || !tsd)
+ return;
+
+ if (bl->type == BL_MOB)
+ send_mob_info(bl, &tsd->bl, *target);
+ else if (bl->type == BL_PC)
+ send_pc_info(bl, &tsd->bl, *target);
+ else if (bl->type == BL_NPC)
+ send_npc_info(bl, &tsd->bl, *target);
+}
+
+void eclif_set_unit_walking(struct block_list* bl, TBL_PC *tsd,
+ struct unit_data* ud, enum send_target *target)
+{
+ TBL_PC *sd = BL_CAST(BL_PC, ud->bl);
+ if (!sd || !pc_isinvisible(sd))
+ send_advmoving(ud, tsd ? &tsd->bl : bl, *target);
+}
+
+void eclif_move(struct unit_data *ud)
+{
+ TBL_PC *sd = BL_CAST(BL_PC, ud->bl);
+ if (!sd || !pc_isinvisible(sd))
+ send_advmoving(ud, ud->bl, AREA_WOS);
+}