微信扫一扫 分享朋友圈

已有 1082 人浏览分享

[服務器疑問] 求助!添加持續掉血類傷害後,會出現隨機返回介面(待測試)

[複製鏈接]

初窺門道

Rank: 2

230

威望

732

金錢

338

A幣
主題
32
帖子
64
精華
1
綜合社群主題發文量
0
電玩社群主題發文量
0
娛樂社群主題發文量
0
技術社群主題發文量
32
閱讀權限
20
註冊時間
2021-11-15
  • TA的每日心情
    奮鬥
    2024-1-28 13:17
  • 簽到天數: 1 天

    連續簽到: 1 天

    [LV.1]初來乍到

    chenhui540 發表於  2023-4-22 19:06:08 | 顯示全部樓層 | 閱讀模式
    本帖最後由 chenhui540 於 2023-5-1 12:35 編輯

    1.png
    2.png

    修過過的內容


            duration += from.getStat().dotTime * 1000;
            long aniTime = duration;
            /*if (skilz != null) {
                aniTime += skilz.getAnimationTime();
            }*/

            status.setCancelTask(aniTime);
            if (poison && getHp() > 1) {
                //if (getStats().isBoss()) {
                //    return;
                //}
                if (status.getchr() != null) {
                    return;
                }
                status.setDotTime(duration);
                int poisonDot = from.getStat().dot;
                int damageIncrease = from.getStat().getDamageIncrease(eff.getSourceId());
                if (damageIncrease > eff.getDOT()) {
                    poisonDot += damageIncrease;
                } else {
                    poisonDot += eff.getDOT();
                }
                if (from.isAdmin()) {
                    from.dropMessage(6, "[持續傷害] 開始處理效果 - 技能ID:" + eff.getSourceId());
                    from.dropMessage(6, "[持續傷害] 加成 - 技能ID:" + eff.getDOT() + " 被動: " + from.getStat().dot + " 被動加成: " + damageIncrease + " 最終加成:" + poisonDot);
                }
                int poisonDamage = (int) (aniTime / 1000 * ((int) (poisonDot * from.getStat().getCurrentMaxBaseDamage() / 100.0D) / 2));
                int damagex = (int) (((getHp() > poisonDamage) ? poisonDamage : (getHp() - 1)) / (aniTime / 1000));
                status.setValue(status.getStati(), damagex);

                if (from.isAdmin()) {
                    from.dropMessage(6, "[持續傷害] 持續傷害: " + ((getHp() > poisonDamage) ? poisonDamage : (getHp() - 1)) + " 持續時間:" + aniTime + " 持續掉血:" + status.getX());
                }
                status.setPoisonSchedule(status.getX(), from);
            } else if (statusSkill == 4111003 || statusSkill == 14111001) { // shadow web




                try {
                    poisons.add(status);
                    status.scheduledoPoison(this);//持续掉血
                } finally {
                    poisonsLock.writeLock().unlock();
                }



        private boolean reflect = false;
        private long cancelTime = 0;
        private long dotTime = 0;
        private boolean newpoison = true;


        public final void cancelPoisonSchedule(MapleMonster mm) {
            mm.doPoison(this, weakChr);
            this.poisonSchedule = 0;
            this.weakChr = null;
        }

        public WeakReference<MapleCharacter> getchr() {
            return this.weakChr;
        }

        public void setDotTime(long duration) {
            this.dotTime = duration;
        }

        public long getDotTime() {
            return this.dotTime;
        }

        public void setnewpoison(boolean s) {
            this.newpoison = s;
        }

        public void scheduledoPoison(final MapleMonster mon) {
            final java.util.Timer timer = new java.util.Timer(true);
            final long time = System.currentTimeMillis();
            final MonsterStatusEffect eff = this;
            if (newpoison) {
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        if (time + getDotTime() > System.currentTimeMillis() && mon.isAlive()) {
                            //每次需要执行的代码放到这里面。  
                            //if (weakChr.get().isAdmin()) {
                            //      weakChr.get().dropMessage(6, "[持续伤害] 持续伤害");
                            //}
                            setnewpoison(false);
                            mon.doPoison(eff, weakChr);
                        } else {
                            setnewpoison(true);
                            //cancelPoisonSchedule(mon);
                            timer.cancel();
                        }
                    }
                };
                timer.schedule(task, 0, 1000);
            }
        }





    添加持續掉血類傷害後,會出現隨機返回介面的情況,有時候第一次攻擊就會返回介面,持續掉血的方法,是從TMS端裡抄襲的,請問,問題大概出現在什麼地方呢?有經驗的朋友,希望能指教一下!謝謝!!

    6.png



    補充:當我開啟MaplePacketEncoder.java 的封包發送後,出現返回介面的概率很少出現。


                if (ServerConstants.DEBUG) {
                    int packetLen = inputInitialPacket.length;
                    int pHeader = readFirstShort(inputInitialPacket);
                    String pHeaderStr = Integer.toHexString(pHeader).toUpperCase();
                    pHeaderStr = StringUtil.getLeftPaddedStr(pHeaderStr, '0', 4);
                    String op = lookupRecv(pHeader);
                    String Recv = "伺服端發送 " + op + " [" + pHeaderStr + "] (" + packetLen + ")\r\n";
                    if (packetLen <= 50000) {
                        //String RecvTo = Recv + HexTool.toString(inputInitialPacket) + "\r\n" + HexTool.toStringFromAscii(inputInitialPacket);//數據包解析
                        String RecvTo = Recv + HexTool.toString(inputInitialPacket);
                        System.out.println(RecvTo + "\r\n");
                    }
                }



    共收到 0 A幣
    打賞榜
    暫無
    暫無
    暫無
    暫無
    ----
    暫無
    ----
    暫無
    ----
    暫無
    ----

    集團新軍

    Rank: 1

    140

    威望

    286

    金錢

    20

    A幣
    主題
    1
    帖子
    20
    精華
    1
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    1
    閱讀權限
    10
    註冊時間
    2022-10-6

    該用戶從未簽到

    EKen 發表於 2023-4-29 04:33:00 | 顯示全部樓層
    檢查看看 MapleClient -> getSession().close(); 是否被調用

    初窺門道

    Rank: 2

    230

    威望

    732

    金錢

    338

    A幣
    主題
    32
    帖子
    64
    精華
    1
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    32
    閱讀權限
    20
    註冊時間
    2021-11-15
  • TA的每日心情
    奮鬥
    2024-1-28 13:17
  • 簽到天數: 1 天

    連續簽到: 1 天

    [LV.1]初來乍到

     樓主| chenhui540 發表於 2023-4-30 17:14:56 | 顯示全部樓層
    本帖最後由 chenhui540 於 2023-4-30 17:16 編輯

    問題已經初步得到處理,也許是端的架構問題,GMS的端一版用的都是mina-core的支援函式庫,而臺灣的版本已經改良成更為穩定的netty,關於這個問題,在R站裡有個相關的文章
    https://forum.ragezone.com/threads/soft-dc-fix.1120766/

    但是具體操作的方法我也看不懂,我用了一個很笨的办法,暫時處理掉了這個問題。

    MaplePacketEncoder.java


                try {
                    final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
                    MapleCustomEncryption.encryptData(unencrypted); // Encrypting Data
                    send_crypto.crypt(unencrypted); // Crypt it with IV
                    System.arraycopy(header, 0, ret, 0, 4); // Copy the header > "Ret", first 4 bytes
                    } finally {
                        FileoutputUtil.log(FileoutputUtil.PacketEx_Log,"");//添加列印文檔輸出
                        mutex.unlock();
                }

    添加列印文檔輸出,然後把輸出的文檔改成隻讀,防止檔無限變大,這樣在發包的地方等於安裝了一個分割裝置,這樣基本上不會在出現返回介面的問題了 !
    這個方法雖然很有效果,但是自我感覺不是太好!有沒有其它的寫法,可以取代這個方法的,請指教一下!!應該怎麼寫,因為本人很小白

    集團新軍

    Rank: 1

    140

    威望

    286

    金錢

    20

    A幣
    主題
    1
    帖子
    20
    精華
    1
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    1
    閱讀權限
    10
    註冊時間
    2022-10-6

    該用戶從未簽到

    EKen 發表於 2023-5-1 07:43:30 | 顯示全部樓層
    本帖最後由 EKen 於 2023-5-1 07:47 編輯

    不建議 在 encode or  decode 時 無條件 Log Packet這在多人時 會導致 I/O 執行頻率過高

    https://forum.ragezone.com/threads/soft-dc-fix.1120766/

    上述文章

    Think back to our initial solutions: We thought there would be concurrency issues with the encrypWe thought there would be concurrency issues with the encryption IVs, so we fixed it. But there is a bigger concurrency issue at play here. When we send packets from various threads at the same time, we have no guarantee of orderingtion IVs

    問題點

    文章所提供的解決方法

    mina encode 中修改
    1. if (client != null) {
    2.    // ...
    3.    IoBuffer buffer = IoBuffer.wrap(ret);
    4.    session.write(buffer);
    5. }
    複製代碼



    除了第一次的封包發送, 其餘使用 IoSession 而不是 ProtocolEncoderOutput

    初窺門道

    Rank: 2

    230

    威望

    732

    金錢

    338

    A幣
    主題
    32
    帖子
    64
    精華
    1
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    32
    閱讀權限
    20
    註冊時間
    2021-11-15
  • TA的每日心情
    奮鬥
    2024-1-28 13:17
  • 簽到天數: 1 天

    連續簽到: 1 天

    [LV.1]初來乍到

     樓主| chenhui540 發表於 2023-5-1 12:29:12 | 顯示全部樓層
    很感謝你的幫助!我現在嘗試替換了源碼的內容

    未修改之前:

    public class MaplePacketEncoder implements ProtocolEncoder {

        @Override
        public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput out) throws Exception {
            final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);

            if (client != null) {
                final MapleAESOFB send_crypto = client.getSendCrypto();

                final byte[] inputInitialPacket = ((byte[]) message);
                final byte[] unencrypted = new byte[inputInitialPacket.length];
                System.arraycopy(inputInitialPacket, 0, unencrypted, 0, inputInitialPacket.length); // Copy the input > "unencrypted"
                final byte[] ret = new byte[unencrypted.length + 4]; // Create new bytes with length = "unencrypted" + 4

                final Lock mutex = client.getLock();
                mutex.lock();
                try {
                    final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
                    MapleCustomEncryption.encryptData(unencrypted); // Encrypting Data
                    send_crypto.crypt(unencrypted); // Crypt it with IV
                    System.arraycopy(header, 0, ret, 0, 4); // Copy the header > "Ret", first 4 bytes
                } finally {
                    mutex.unlock();
                }
                System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length); // Copy the unencrypted > "ret"
                out.write(IoBuffer.wrap(ret));
            } else { // no client object created yet, send unencrypted (hello)
                out.write(IoBuffer.wrap(((byte[]) message)));
            }
        }



    修改后:

    public class MaplePacketEncoder implements ProtocolEncoder {

        @Override
        public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput out) throws Exception {
            final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);

            if (client != null) {
                final MapleAESOFB send_crypto = client.getSendCrypto();

                final byte[] inputInitialPacket = ((byte[]) message);

                final byte[] unencrypted = new byte[inputInitialPacket.length];
                System.arraycopy(inputInitialPacket, 0, unencrypted, 0, inputInitialPacket.length); // Copy the input > "unencrypted"
                final byte[] ret = new byte[unencrypted.length + 4]; // Create new bytes with length = "unencrypted" + 4

                final Lock mutex = client.getLock();
                mutex.lock();
                try {
                    final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
                    MapleCustomEncryption.encryptData(unencrypted); // Encrypting Data
                    send_crypto.crypt(unencrypted); // Crypt it with IV
                    System.arraycopy(header, 0, ret, 0, 4); // Copy the header > "Ret", first 4 bytes
                    System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length); // Copy the unencrypted > "ret"
                   
                    session.write(IoBuffer.wrap(ret));//除了第一次的封包發送, 其餘使用 IoSession 而不是 ProtocolEncoderOutput
                } finally {
                    mutex.unlock();
                }
            } else { // no client object created yet, send unencrypted (hello)
                out.write(IoBuffer.wrap(((byte[]) message)));
            }
        }



    不知道這樣修改對不對,我有雙開上線測試打怪了一小時左右,沒有出現斷開連接的情況了!很感謝你的幫助!!!

    集團新軍

    Rank: 1

    140

    威望

    286

    金錢

    20

    A幣
    主題
    1
    帖子
    20
    精華
    1
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    1
    閱讀權限
    10
    註冊時間
    2022-10-6

    該用戶從未簽到

    EKen 發表於 2023-5-1 20:59:59 | 顯示全部樓層
    chenhui540 發表於 2023-5-1 12:29
    很感謝你的幫助!我現在嘗試替換了源碼的內容

    未修改之前:

    對的
    您需要登錄後才可以回帖 登錄 | 註冊會員

    本版積分規則

    64

    發文

    732

    金錢

    338

    A幣

    ----------榮譽勳章----------

    熱門推薦
    圖文推薦
    • 聯繫我們

    小黑屋|AICL社群娛樂集團

    GMT+8, 2024-11-22 15:10 , 網路刷新 0.106730 秒 .

    歡迎來到 AICL網路社群

    版權AICL社群所有 2011-2021.

    Total:123 Today:213 Online:322