微信扫一扫 分享朋友圈

已有 553 人浏览分享

[服務器教學] GMS專用 魔法轉盤修復

[複製鏈接]

初窺門道

Rank: 2

327

威望

413

金錢

216

A幣
主題
13
帖子
66
精華
5
綜合社群主題發文量
0
電玩社群主題發文量
0
娛樂社群主題發文量
0
技術社群主題發文量
13
閱讀權限
20
註冊時間
2019-8-9

精華作者勳章

  • TA的每日心情

    2021-6-8 20:12
  • 簽到天數: 14 天

    連續簽到: 0 天

    [LV.3]偶爾看看II

    精華 a894985459 發表於  2023-6-5 22:55:39 | 顯示全部樓層 | 閱讀模式
    本帖最後由 a894985459 於 2023-6-5 23:06 編輯

    沒錯 又是我
    這項功能僅限於國際版可使用MAGIC WHEEL 就是本日的主角

    我不確定各端口的修復程度到底如何 我先以我117的來講解
    首先找到你伺服器內的
    1. recvopsGMS.properties
    複製代碼

    以及
    1. sendopsGMS.properties
    複製代碼
    分別檢查封包是否如下
    recvopsGMS.properties
    1. MAGIC_WHEEL = 463
    複製代碼


    sendopsGMS.properties
    1. MAGIC_WHEEL = 201
    複製代碼


    如果不是 請修正
    接下來進入遊戲中後 魔法轉盤已經可以正常呼叫出來
    若無法使用 請添加以下語法

    找到World.java

    1. public class World {
    複製代碼
    下方新增宣告(如有則跳過)
    1. private static final Map<Integer, Integer> magicWheelCache = new HashMap();
    複製代碼


    轉到InventoryHandler.java
    隨意一處增加以下語法(如有則跳過)
    1.                  public static void UseMagicWheel(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
    2.                                  
    3.                if ((!chr.isAlive()) || (chr.hasBlockedInventory()) || (chr.isInBlockedMap()) || (chr.inPVP())) {
    4.                  c.getSession().write(CWvsContext.MagicWheelAction(8));
    5.                  return;
    6.                }
    7.            
    8.                byte mode = slea.readByte();
    9.                if ((mode == 0) && (World.hasWheelCache(chr.getId()))) {
    10.                  World.removeFromWheelCache(chr.getId());
    11.                } else if (mode == 2) {
    12.                  slea.skip(4);
    13.                  short toUseSlot = (short)slea.readInt();
    14.                  int tokenId = slea.readInt();
    15.                  Item toUse = chr.getInventory(GameConstants.getInventoryType(tokenId)).getItem(toUseSlot);
    16.                  if ((toUse == null) || (toUse.getQuantity() < 1) || (toUse.getItemId() != tokenId) || tokenId != 4400000) {
    17.                    c.getSession().write(CWvsContext.MagicWheelAction(6));
    18.                    return;
    19.                  }
    20.                  if ((chr.getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.USE).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.SETUP).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.ETC).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.CASH).getNumFreeSlot() < 2)) {
    21.                    c.getSession().write(CWvsContext.MagicWheelAction(7));
    22.                    return;
    23.                  }
    24.                  if (World.hasWheelCache(chr.getId())) {
    25.                    c.getSession().write(CWvsContext.MagicWheelAction(8));
    26.                    return;
    27.                  }
    28.                  MapleInventoryManipulator.removeFromSlot(c, GameConstants.getInventoryType(tokenId), toUseSlot, (short)1, false);
    29.                  List rewards = new ArrayList();
    30.                  int i = 0;
    31.                  int itemid = 0;
    32.                  while (i < 10) {
    33.                    if (i < 6) {
    34.                      itemid = GameConstants.normalMagicWheel[Randomizer.nextInt(GameConstants.normalMagicWheel.length)];
    35.                      if (!rewards.contains(Integer.valueOf(itemid))) {
    36.                        rewards.add(Integer.valueOf(itemid));
    37.                        i++;
    38.                      }
    39.                    } else if (i < 9) {
    40.                      itemid = GameConstants.rareMagicWheel[Randomizer.nextInt(GameConstants.rareMagicWheel.length)];
    41.                      if (!rewards.contains(Integer.valueOf(itemid))) {
    42.                        rewards.add(Integer.valueOf(itemid));
    43.                        i++;
    44.                      }
    45.                    } else {
    46.                      itemid = GameConstants.superMagicWheel[Randomizer.nextInt(GameConstants.superMagicWheel.length)];
    47.                      if (!rewards.contains(Integer.valueOf(itemid))) {
    48.                        rewards.add(Integer.valueOf(itemid));
    49.                        i++;
    50.                      }
    51.                    }
    52.                  }
    53.                  Collections.shuffle(rewards);
    54.                  int prizePos = Randomizer.nextInt(10);
    55.                  World.addToWheelCache(chr.getId(), ((Integer)rewards.get(prizePos)).intValue());
    56.                  c.getSession().write(CWvsContext.MagicWheelAction(3, String.valueOf(chr.getId()), rewards, prizePos));
    57.                } else if (mode == 4) {
    58.                  String data = slea.readMapleAsciiString();
    59.                  if ((!data.equals(String.valueOf(chr.getId()))) || (!World.hasWheelCache(chr.getId()))) {
    60.                    c.getSession().write(CWvsContext.MagicWheelAction(8));
    61.                    return;
    62.                  }
    63.                  int itemId = World.removeFromWheelCache(chr.getId());
    64.                  if (itemId > 0) {
    65.                    Item item = MapleInventoryManipulator.addbyId_Gachapon(c, itemId, (short)1);
    66.                    if (item == null) {
    67.                      c.getSession().write(CWvsContext.MagicWheelAction(10));
    68.                      return;
    69.                    }
    70.                    if (GameConstants.isSuperMagicWheel(itemId)) {
    71.         c.getSession().write(CWvsContext.getGachaponMega(chr.getName(), " : got a(n)", item, (byte)11, "Wheel of Marvels"));
    72.     }
    73.                  }
    74.                }
    75.                else if (mode != 0) {
    76.                  c.getSession().write(CWvsContext.MagicWheelAction(8));
    77.                }
    78.              }
    79.            
    複製代碼


    轉到CWvsContext.java
    隨意一處增加以下語法(如有則跳過)
    1.             public static byte[] MagicWheelAction(int mode) {
    2.                return MagicWheelAction(mode, null, null, 0);
    3.              }
    4.            
    5.              public static byte[] MagicWheelAction(int mode, String dataKey, List<Integer> ids, int position) {
    6.                MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
    7.            
    8.                mplew.writeShort(SendPacketOpcode.MAGIC_WHEEL.getValue());
    9.                mplew.write(mode);
    10.                if (mode == 3) {
    11.                  mplew.write(ids.size());
    12.                  for (Integer i : ids) {
    13.                    mplew.writeInt(i.intValue());
    14.                  }
    15.                  mplew.writeMapleAsciiString(dataKey);
    16.                  mplew.write(position);
    17.                }
    18.            
    19.                return mplew.getPacket();
    20.              }
    複製代碼
    轉到MapleServerHandler.java
    搜尋
    1. case MAGIC_WHEEL:
    複製代碼


    檢查是否與下方語法相同
    如不是直接替換
    1. case MAGIC_WHEEL:
    2.                 InventoryHandler.UseMagicWheel(slea, c, c.getPlayer());
    3.                 break;
    複製代碼


    轉到GameConstants.java
    隨意一處增加以下語法
    1.              public static final int[] normalMagicWheel = { 4006000, 2050004, 3994102, 3994103, 3994104, 3994102, 3994103, 3994104, 3994105, 2430007 };
    2.            
    3.              public static final int[] rareMagicWheel = { 2028061, 2290285, 2049301, 2049401, 2022326, 2022193, 2049000, 2049001, 2049002 };
    4.            
    5.              public static final int[] superMagicWheel = { 2040804, 2049400, 2028062, 2028061, 2430144, 2430144, 2430144, 2430144, 2290285, 2049100, 2049100, 2049100, 2049100 };
    6.            
    7.               public static boolean isSuperMagicWheel(int itemid) {
    8.                for (int i : superMagicWheel) {
    9.                  if (i == itemid) {
    10.                    return true;
    11.                  }
    12.                }
    13.                return false;
    14.              }
    複製代碼
    編譯後 魔法轉盤應已恢復正常

    課外加碼

    轉盤獎品想要透過資料庫存取可不可以?
    可以 當然可以

    在InventoryHandler.java
    增加以下語法
    1. public static List<Integer> getMagicWheel(int type) {//取得資料庫內轉盤獎勵
    2.         
    3.         Connection con = DatabaseConnection.getConnection();
    4.         try {
    5.             List<Integer> MagicWheel = new ArrayList<Integer>();
    6.             PreparedStatement ps = con.prepareStatement("SELECT * FROM wheeldata WHERE type = ? ORDER BY RAND() LIMIT 10");
    7.             ps.setInt(1, type);
    8.             ResultSet rs = ps.executeQuery();
    9.             while (rs.next()) {
    10.              int itemid = rs.getInt("itemid");
    11.              MagicWheel.add(itemid);
    12.             }
    13.             rs.close();
    14.             ps.close();
    15.             return MagicWheel;
    16.             
    17.         } catch (Exception Ex) {
    18.             Ex.printStackTrace();
    19.             return null;
    20.         }
    21.     }
    複製代碼
    完成後 我們回到
    1. UseMagicWheel
    複製代碼
    這項涵式來
    往下找到類似這段
    1. itemid = GameConstants.normalMagicWheel[Randomizer.nextInt(GameConstants.normalMagicWheel.length)];
    複製代碼

    將其修改為
    1. itemid = new Random().nextInt(getMagicWheel(1).size());
    複製代碼
    各位同學請注意,請記得import Random


    在往下找到
    1. rewards.add(Integer.valueOf(itemid));
    複製代碼
    將其修改為
    1. rewards.add(Integer.valueOf(getMagicWheel(1).get(itemid)));
    複製代碼
    一共會有3段相似的語法
    按照本文修改即可

    往下找到
    1. isSuperMagicWheel
    複製代碼

    1. if (i == itemid) {
    複製代碼
    修改為
    1. for (int i : getMagicWheel(3)) {
    複製代碼


    這邊主要是讓語法去判斷是不是抽到本次轉盤的大獎
    如果是 則會進行轉蛋廣播


    有點程式基礎的相信不用小弟指點
    我還是另外講解一下思路

    首先 新增的
    1. public static List<Integer> getMagicWheel(int type) {
    複製代碼
    這段語法 用於存取資料庫內的獎品資料
    要取得獎品List 當然要先給他要怎麼找

    因此
    1. getMagicWheel(1)
    複製代碼
    即是告訴語法 我要找 type = 1的獎品內容

    回到上方
    你告訴完語法之後 語法接收到了 那他就去資料庫把
    type = 1的獎品內容全部撈出來 轉成List型態
    當然我們前面有下過限制
    也就是
    1. ORDER BY RAND() LIMIT 10
    複製代碼
    懂了嗎?
    我告訴語法 我要type = 1的獎品內容
    但我要隨機的內容 你最多只能給我10個 在多我不要
    因此 當你的資料表內獎品越多
    隨機出來的物品品項也就越隨機

    最後回到資料庫 新增資料表名稱為
    1. wheeldata
    複製代碼

    分別建立兩個Table
    1.名稱為itemid 類型為int 長度11
    2.名稱為type   類型為int 長度11

    其餘不用管
    當然你也可以新增另外的Table 用於告訴自己這是什麼獎品
    並不影響語法的搜索

    以上,若還有不懂請PM或回文告知

    補充說明 使用轉盤的道具是
    4400000、44000001、44000002這三項
    目前本語法僅可使用4400000該項道具我也還在摸索如何讓三項道具都能使用
    若有新消息我會在本文下方補充





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

    初窺門道

    Rank: 2

    327

    威望

    413

    金錢

    216

    A幣
    主題
    13
    帖子
    66
    精華
    5
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    13
    閱讀權限
    20
    註冊時間
    2019-8-9

    精華作者勳章

  • TA的每日心情

    2021-6-8 20:12
  • 簽到天數: 14 天

    連續簽到: 0 天

    [LV.3]偶爾看看II

     樓主| a894985459 發表於 2023-6-6 22:27:38 | 顯示全部樓層
    補充一下
    由於GMS客戶端限制問題
    原先的getGachaponMega會有字數限制
    除非各位的客戶端已經Unpacket可以修改字串
    否則中獎訊息改為中文的話 會造成字體重疊
    因此建議修改為下方的語法
    1. final StringBuilder sb = new StringBuilder();
    2.                     addMedalString(c.getPlayer(), sb);
    3.                     sb.append("<魔法轉盤中獎訊息>" + c.getPlayer().getName());
    4.                     sb.append(" : ");
    5.                     sb.append("是我轉到的超級獎品!");
    6.                        //c.getSession().write(CWvsContext.getGachaponMega(chr.getName(), " :我從魔法輪盤中轉到了", item, (byte)11, "!!"));
    7.                        World.Broadcast.broadcastSmega(CWvsContext.itemMegaphone(sb.toString(), true, c.getChannel(), item));
    8.                        
    9.                      }
    複製代碼

    利用道具廣播的原生功能來完成中獎訊息廣播


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

    本版積分規則

    66

    發文

    413

    金錢

    216

    A幣

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

    精華作者勳章

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

    小黑屋|AICL社群娛樂集團

    GMT+8, 2024-4-19 23:31 , 網路刷新 0.108152 秒 .

    歡迎來到 AICL網路社群

    版權AICL社群所有 2011-2021.

    Total:123 Today:213 Online:322