summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/char.cpp9
-rw-r--r--src/map/atcommand.cpp25
-rw-r--r--src/map/atcommand.hpp2
-rw-r--r--src/map/pc.cpp23
-rw-r--r--src/map/skill.cpp2
5 files changed, 49 insertions, 12 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp
index 417b0d3..4d930f1 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -812,8 +812,17 @@ void create_online_files(void)
// display each player.
for (CharPair& cd : char_keys)
{
+ CharData *p = nullptr;
+
if (!server_for(&cd))
continue;
+
+ p = cd.data.get();
+
+ // failsafe
+ if (bool(p->option & Opt0::HIDE))
+ continue;
+
players++;
FPRINTF(fp2, " <tr>\n"_fmt);
// displaying the character name
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 3058584..459672d 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -337,6 +337,31 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
}
}
+bool can_use_atcommand(dumb_ptr<map_session_data> sd, ZString message)
+{
+ nullpo_retr(false, sd);
+
+ if (!message.startswith('@'))
+ return false;
+
+ XString command;
+ ZString arg;
+ asplit(message, &command, &arg);
+
+ GmLevel gmlvl = pc_isGM(sd);
+
+ if (battle_config.atcommand_gm_only != 0 && !gmlvl)
+ return false; // level 0 commands are disabled
+
+ Option<P<AtCommandInfo>> info_ = atcommand(command);
+ P<AtCommandInfo> info = TRY_UNWRAP(info_,
+ {
+ return false; // command not found
+ });
+
+ return gmlvl.satisfies(info->level);
+}
+
Option<Borrowed<AtCommandInfo>> atcommand(XString cmd)
{
if (cmd.startswith('@'))
diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp
index 4c0e421..b77f7e5 100644
--- a/src/map/atcommand.hpp
+++ b/src/map/atcommand.hpp
@@ -30,6 +30,8 @@ namespace map
bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
ZString message, GmLevel gmlvl);
+bool can_use_atcommand(dumb_ptr<map_session_data> sd, ZString message);
+
bool atcommand_config_read(ZString cfgName);
void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd);
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 6b19899..77bb956 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -779,25 +779,26 @@ int pc_authok(AccountId id, int login_id2, ClientVersion client_version,
// イベント関係の初期化
sd->eventqueuel.clear();
- // 位置の設定
- pc_setpos(sd, sd->status.last_point.map_, sd->status.last_point.x,
- sd->status.last_point.y, BeingRemoveWhy::GONE);
-
{
Opt0 old_option = sd->status.option;
sd->status.option = Opt0::ZERO;
- // This would leak information.
- // It's better to make it obvious that players can see you.
- if (false && bool(old_option & Opt0::INVISIBILITY))
- is_atcommand(sd->sess, sd, "@invisible"_s, GmLevel());
+ if (bool(old_option & Opt0::INVISIBILITY) && can_use_atcommand(sd, "@invisible"_s)) {
+ // prevent leaking by first applying hide before status_change
+ sd->status.option |= Opt0::HIDE;
+ sd->status.option |= Opt0::INVISIBILITY;
+ clif_status_change(sd, StatusChange::CLIF_OPTION_SC_INVISIBILITY, 1);
+ } else if (bool(old_option & Opt0::HIDE) && can_use_atcommand(sd, "@hide"_s)) {
+ sd->status.option |= Opt0::HIDE;
+ }
- if (bool(old_option & Opt0::HIDE))
- is_atcommand(sd->sess, sd, "@hide"_s, GmLevel());
- // atcommand_hide might already send it, but also might not
clif_changeoption(sd);
}
+ // 位置の設定
+ pc_setpos(sd, sd->status.last_point.map_, sd->status.last_point.x,
+ sd->status.last_point.y, BeingRemoveWhy::GONE);
+
// パーティ、ギルドデータの要求
if (sd->status.party_id
&& party_search(sd->status.party_id).is_none())
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index d9a7717..cf99af8 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -1090,7 +1090,7 @@ int skill_status_change_clear(dumb_ptr<block_list> bl, int type)
*opt1 = Opt1::ZERO;
*opt2 = Opt2::ZERO;
*opt3 = Opt3::ZERO;
- *option = Opt0::ZERO;
+ //*option = Opt0::ZERO;
if (type == 0 || type & 2)
clif_changeoption(bl);