summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/battle.h3
-rw-r--r--src/map/clif.c197
-rw-r--r--src/map/clif.h31
-rw-r--r--src/map/itemdb.c5
-rw-r--r--src/map/packets.h4
-rw-r--r--src/map/packets_struct.h17
7 files changed, 257 insertions, 2 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 8c0beede2..1e65131e8 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7320,6 +7320,8 @@ static const struct battle_data {
{ "features/rodex_use_accountmail", &battle_config.feature_rodex_use_accountmail, 0, 0, 1, },
{ "features/enable_homun_autofeed", &battle_config.feature_enable_homun_autofeed, 1, 0, 1, },
{ "storage_use_item", &battle_config.storage_use_item, 0, 0, 1, },
+ { "features/enable_attendance_system", &battle_config.feature_enable_attendance_system,1, 0, 1, },
+ { "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, },
};
#ifndef STATS_OPT_OUT
/**
diff --git a/src/map/battle.h b/src/map/battle.h
index b4a404657..3236bfe0f 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -564,6 +564,9 @@ struct Battle_Config {
int feature_enable_homun_autofeed;
int storage_use_item;
+
+ int feature_enable_attendance_system;
+ int feature_attendance_endtime;
};
/* criteria for battle_config.idletime_critera */
diff --git a/src/map/clif.c b/src/map/clif.c
index 5bab7ef15..e57f6e01b 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -20413,6 +20413,194 @@ void clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable)
#endif
}
+bool clif_parse_attendance_db(void)
+{
+ struct config_t attendance_conf;
+ struct config_setting_t *attendance = NULL, *it = NULL;
+ const char *config_filename = "db/attendance_db.conf"; // FIXME hardcoded name
+ int i = 0;
+
+ if (!libconfig->load_file(&attendance_conf, config_filename))
+ return false;
+ attendance = libconfig->lookup(&attendance_conf, "attendance_db");
+
+ VECTOR_CLEAR(clif->attendance_data);
+
+ while ((it = libconfig->setting_get_elem(attendance, i++))) {
+ clif->attendancedb_libconfig_sub(it, i, config_filename);
+ }
+
+ libconfig->destroy(&attendance_conf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename);
+ return true;
+}
+
+bool clif_attendancedb_libconfig_sub(struct config_setting_t *it, int n, const char *source)
+{
+ struct attendance_entry entry = { 0 };
+ int i32 = 0;
+
+ nullpo_ret(it);
+ nullpo_ret(source);
+
+ if (!itemdb->lookup_const(it, "ItemID", &i32) || i32 < 0) {
+ ShowWarning("clif_attendancedb_libconfig_sub: unknown item %d, entry #%d, skipping.\n", i32, n);
+ return false;
+ }
+ entry.nameid = i32;
+
+ if (!libconfig->setting_lookup_int(it, "Amount", &i32) || i32 < 1) {
+ ShowWarning("clif_attendancedb_libconfig_sub: invalid amount %d, entry #%d, skipping.\n", i32, n);
+ return false;
+ }
+ entry.qty = i32;
+
+ VECTOR_ENSURE(clif->attendance_data, 1, 1);
+ VECTOR_PUSH(clif->attendance_data, entry);
+ return true;
+}
+
+bool clif_attendance_timediff(struct map_session_data *sd)
+{
+ int64 timediff;
+
+ nullpo_retr(false, sd);
+
+ timediff = (time(NULL) / (60 * 60 * 24)) - (sd->status.attendance_timer / (60 * 60 * 24));
+
+ if (timediff <= 0)
+ return false;
+ return true;
+}
+time_t clif_attendance_getendtime(void)
+{
+ time_t timestamp;
+ struct tm tmtime = { 0 };
+ int year = 0, month = 0, day = 0;
+ char timestring[9];
+
+ sprintf(timestring, "%8d", battle_config.feature_attendance_endtime);
+ sscanf(timestring, "%4d%2d%2d", &year, &month, &day);
+
+ tmtime.tm_year = year - 1900;
+ tmtime.tm_mon = month - 1;
+ tmtime.tm_mday = day;
+
+ timestamp = mktime(&tmtime);
+
+ return timestamp;
+}
+
+void clif_parse_open_ui_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2)));
+void clif_parse_open_ui_request(int fd, struct map_session_data *sd)
+{
+
+ const struct PACKET_CZ_OPEN_UI *p = RP2PTR(fd);
+
+ if (clif->attendance_getendtime() < time(NULL)) {
+ clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED);
+ return;
+ }
+
+ if (battle_config.feature_enable_attendance_system != 1)
+ return;
+
+ clif->open_ui(sd, p->UIType);
+}
+
+void clif_open_ui(struct map_session_data *sd, int8 UIType)
+{
+#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404
+ int claimed = 0;
+ struct PACKET_ZC_OPEN_UI p;
+
+ nullpo_retv(sd);
+
+ p.PacketType = 0xAE2;
+ switch (UIType) {
+ case 5: // client will send 5 for the request but requires to receive ATTENDANCE_UI (7) to open the correct ui.
+ if (clif->attendance_timediff(sd) != true)
+ ++claimed;
+ else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data))
+ sd->status.attendance_count = 0;
+ p.UIType = ATTENDANCE_UI;
+ p.data = sd->status.attendance_count * 10 + claimed;
+ break;
+ default:
+ ShowWarning("clif_open_ui: Requested UI (%d) is not implemented yet.\n", UIType);
+ return;
+ }
+
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+#else
+ ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404.\n");
+#endif
+}
+
+void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2)));
+void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd)
+{
+#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404
+
+ struct rodex_message msg = { 0 };
+ struct attendance_entry *entry;
+ int attendance_count;
+ char title[RODEX_TITLE_LENGTH], body[MAIL_BODY_LENGTH];
+
+ if (clif->attendance_getendtime() < time(NULL)) {
+ clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED);
+ return;
+ }
+
+ if (battle_config.feature_enable_attendance_system != 1)
+ return;
+
+ if (clif->attendance_timediff(sd) != true)
+ return;
+
+ if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data))
+ sd->status.attendance_count = 0;
+
+ attendance_count = sd->status.attendance_count;
+ ++sd->status.attendance_count;
+ sd->status.attendance_timer = time(NULL);
+
+ msg.receiver_id = sd->status.char_id;
+ sprintf(title, msg_txt(545), attendance_count + 1);
+ sprintf(body, msg_txt(545), attendance_count + 1);
+
+ entry = &VECTOR_INDEX(clif->attendance_data, attendance_count);
+ msg.items[0].item.nameid = entry->nameid;
+ msg.items[0].item.amount = entry->qty;
+ msg.items[0].item.identify = 1;
+ msg.type = MAIL_TYPE_NPC | MAIL_TYPE_ITEM;
+
+ safestrncpy(msg.sender_name, msg_txt(544), NAME_LENGTH);
+ safestrncpy(msg.title, title, RODEX_TITLE_LENGTH);
+ safestrncpy(msg.body, body, MAIL_BODY_LENGTH);
+ msg.send_date = (int)time(NULL);
+ msg.expire_date = (int)time(NULL) + RODEX_EXPIRE;
+
+ intif->rodex_sendmail(&msg);
+ clif->ui_action(sd, 0, sd->status.attendance_count);
+#else
+ ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404.\n");
+#endif
+}
+
+void clif_ui_action(struct map_session_data *sd, int32 UIType, int32 data)
+{
+
+ struct PACKET_ZC_UI_ACTION p;
+
+ nullpo_retv(sd);
+
+ p.PacketType = 0xAF0;
+ p.UIType = UIType;
+ p.data = data;
+
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+}
/*==========================================
* Main client packet processing function
*------------------------------------------*/
@@ -21509,4 +21697,13 @@ void clif_defaults(void) {
// -- Hat Effect
clif->hat_effect = clif_hat_effect;
clif->hat_effect_single = clif_hat_effect_single;
+
+ clif->pAttendanceDB = clif_parse_attendance_db;
+ clif->attendancedb_libconfig_sub = clif_attendancedb_libconfig_sub;
+ clif->attendance_timediff = clif_attendance_timediff;
+ clif->attendance_getendtime = clif_attendance_getendtime;
+ clif->pOpenUIRequest = clif_parse_open_ui_request;
+ clif->open_ui = clif_open_ui;
+ clif->pAttendanceRewardRequest = clif_parse_attendance_reward_request;
+ clif->ui_action = clif_ui_action;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index eee978aac..f0eaaf6eb 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -388,6 +388,7 @@ enum clif_messages {
MSG_NPC_WORK_IN_PROGRESS = 0x783, // FIXME[Haru]: This seems to be 0x784 in the msgstringtable files I found.
MSG_REINS_CANT_USE_MOUNTED = 0x78b, // FIXME[Haru]: This seems to be 0x785 in the msgstringtalbe files I found.
MSG_PARTY_LEADER_SAMEMAP = 0x82e, //< It is only possible to change the party leader while on the same map.
+ MSG_ATTENDANCE_UNAVAILABLE = 0xd92, ///< Attendance Check failed. Please try again later.
};
/**
@@ -575,6 +576,19 @@ enum CZ_CONFIG {
CZ_CONFIG_HOMUNCULUS_AUTOFEEDING = 3,
};
/**
+* Client UI types
+* used with packet 0xAE2 to request the client to open a specific ui
+**/
+enum ui_types {
+ BANK_UI = 0,
+ STYLIST_UI,
+ CAPTCHA_UI,
+ MACRO_UI,
+ TIPBOX_UI = 5,
+ RENEWQUEST_UI,
+ ATTENDANCE_UI
+};
+/**
* Structures
**/
typedef void (*pFunc)(int, struct map_session_data *); //cant help but put it first
@@ -599,6 +613,12 @@ struct merge_item {
int16 nameid;
};
+/* attendance data */
+struct attendance_entry {
+ int nameid;
+ int qty;
+};
+
/**
* Clif.c Interface
**/
@@ -628,6 +648,8 @@ struct clif_interface {
bool ally_only;
/* */
struct eri *delayed_damage_ers;
+ /* */
+ VECTOR_DECL(struct attendance_entry) attendance_data;
/* core */
int (*init) (bool minimal);
void (*final) (void);
@@ -1419,6 +1441,15 @@ struct clif_interface {
/* Hat Effect */
void (*hat_effect) (struct block_list *bl, struct block_list *tbl, enum send_target target);
void (*hat_effect_single) (struct block_list *bl, uint16 effectId, bool enable);
+
+ bool (*pAttendanceDB) (void);
+ bool (*attendancedb_libconfig_sub) (struct config_setting_t *it, int n, const char *source);
+ bool (*attendance_timediff) (struct map_session_data *sd);
+ time_t (*attendance_getendtime) (void);
+ void (*pOpenUIRequest) (int fd, struct map_session_data *sd);
+ void (*open_ui) (struct map_session_data *sd, int8 UIType);
+ void (*pAttendanceRewardRequest) (int fd, struct map_session_data *sd);
+ void (*ui_action) (struct map_session_data *sd, int32 UIType, int32 data);
};
#ifdef HERCULES_CORE
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 17a73400a..7f0ebb39c 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -2387,6 +2387,8 @@ void itemdb_read(bool minimal) {
if (minimal)
return;
+ itemdb->name_constants();
+
itemdb->read_combos();
itemdb->read_groups();
itemdb->read_chains();
@@ -2619,6 +2621,7 @@ void do_final_itemdb(void) {
itemdb->options->destroy(itemdb->options, itemdb->options_final_sub);
itemdb->destroy_item_data(&itemdb->dummy, 0);
db_destroy(itemdb->names);
+ VECTOR_CLEAR(clif->attendance_data);
}
void do_init_itemdb(bool minimal) {
@@ -2637,6 +2640,8 @@ void do_init_itemdb(bool minimal) {
/** it failed? we disable it **/
if (battle_config.feature_roulette == 1 && !clif->parse_roulette_db())
battle_config.feature_roulette = 0;
+ VECTOR_INIT(clif->attendance_data);
+ clif->pAttendanceDB();
}
void itemdb_defaults(void) {
itemdb = &itemdb_s;
diff --git a/src/map/packets.h b/src/map/packets.h
index 7fbb209fd..db98cdc28 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -3427,7 +3427,7 @@ packet(0x96e,-1,clif->ackmergeitems);
// 2016-03-23aRagexeRE
#if PACKETVER >= 20160323
// new packets
- packet(0x0a68,3);
+ packet(0x0a68,3,clif->pOpenUIRequest);
packet(0x0a69,6);
packet(0x0a6a,12);
packet(0x0a6b,-1);
@@ -3970,7 +3970,7 @@ packet(0x96e,-1,clif->ackmergeitems);
#if PACKETVER >= 20180117
// new packets
- packet(0x0aef,2);
+ packet(0x0aef,2,clif->pAttendanceRewardRequest);
packet(0x0af0,10);
// changed packet sizes
packet(0x0ae9,13);
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 7e154c12c..438084778 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -1712,6 +1712,23 @@ struct PACKET_ZC_MSG_COLOR {
uint32 MessageColor;
} __attribute__((packed));
+struct PACKET_CZ_OPEN_UI {
+ int16 PacketType;
+ int8 UIType;
+} __attribute__((packed));
+
+struct PACKET_ZC_OPEN_UI {
+ int16 PacketType;
+ int8 UIType;
+ int32 data;
+} __attribute__((packed));
+
+struct PACKET_ZC_UI_ACTION {
+ int16 PacketType;
+ int32 UIType;
+ int32 data;
+} __attribute__((packed));
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris