同步操作将从 pws019/MapleStory143 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
本源码来自互联网,仅用作学习交流
Chinese MapleStory Server 143 冒险岛服务端143版本
2019-12-27 Here are the WZ files and SQL files you need 服务端链接:(three ways to download)
[1]百度云:https://pan.baidu.com/s/1geBb9mz 密码:bhfn
[2]Google 云盘(大陆无法访问):https://drive.google.com/open?id=0B9Ls-F4Al3E-T0xobmtkeVVreFU
[3]MEGA网盘(大陆部分地区可以访问):https://mega.nz/#!OQBX0ILZ!PP92J-uexcb6ctzEIz14X7AxdfGC3VKRr-GaExBeuHE
不要用自带的exe文件启动服务端,据说这个文件有木马 don't use exe file to start server,maybe this file is not safe
客户端使用的是国服143版本的客户端,自行下载吧,避免侵权
第n次捣鼓冒险岛,这明明就是一个吃力不讨好的问题。相比冒险岛而言,技术有一些确是很有趣,冒险岛也是童年的回忆。主要还是想搞懂技术。
这个项目的目的不是分享如何启动一个143的服务器而是希望找到志同道合的朋友,一起玩好143服务器。我也不懂,就懂一些java的东西。很多东西还得摸索和学习。目的搞懂到底是如何交互以及如何修复后台的。**比如职业技能修复、活动修复boss修复等等。**那些脚本、Wz修改的都比较简单,不是我的目的。所以希望有大佬或者感兴趣的朋友带带我或者一起学习。**我是真的觉得这个很有趣!!!**当然大佬都比较高冷,觉得我就像个菜鸡
项目所有的东西都是我在网上找的,而且我亲手操作过一遍。就好像别人搭好的台子,玩出自己想玩的东西, 这篇文章只是分享一下怎么启动143的服务器。使用的资源论坛都有!!!
看到论坛上面143服务器的介绍太少了,所以我自己也想尝试一下启动143
听说同步的一些服都是143修复过去的,所以我也想试试,从这里开始。
我也什么都不懂,应该不会被别人利用吧?以下理解都是我从0开始实际操作的
只需要三个东西:
后台源码
gitee上搜索 https://gitee.com/enterprises
143客户端,也就是用户端
一个万能登陆器
下载源码,idea导包。直接在gitee上搜索 maplestory143就有,这个就是fork过来的。
下载这些项目里面介绍的静态文件
只需要用到框出来的文件夹
按照里面的介绍把wz文件配置了, 把里面的config文件夹、script文件夹放到当前项目文件夹下。一个是配置,一个是脚本。都可以热更新的。
wz读的是systemProperties,找到项目启动入口直接加入本地放wz文件夹的地方
在启动的main方法下添加
System.setProperty("wzpath","H:\\play\\source\\wz");
或者配置启动参数也可以 -D,但是换个电脑要重新配麻烦。
config/ scripts我直接拉到项目的根目录了 如下
4.修改路径配置,主要是Mysql配置
启动一个数据库,本地没有数据库就用里面phpstudy启动。有数据库直接导入项目的数据库sql文件。
数据库文件在哪搞?启动一次phpstudy把里面的数据库导出来就行。
下载一个143的客户端,论坛很多
idea启动项目,有启动问题就解决问题,反正我是直接起来了,这里分配给idea启动项目的内存多一点,我给了3g。
-Xms3072m -Xmx3072m
idea启动后会有一个ui界面,点击一下
我嫌太麻烦了直接把这个启动服务端按钮的逻辑添加在main函数后面的代码里面,idea启动就不用再点一次启动服务端了,但是这里有bug不要再点这个按钮就行。
找一个万能登陆器跳过143的账号登录。论坛、各种qq群也有很多,发放在mapstory.exe同级目录就行。目的是跳过盛大的登陆进入游戏。
点击万能登录器直接启动服务。
进入到账号密码登陆页面再用登录器登陆!!!,不然后续会出问题。我之前就是提前点了导致进入大区就直接闪退了。感觉是网络出问题了或者是ip被ban之类的我也不清楚。
账号密码随便填,不存在的自动会创建账户,点击登陆后续就进入游戏了。
第一次操作成功还有点小激动!!!!!
后面就进入游戏,有手就行了。但是有一个问题必会出现。详见下面问题2
我还是坚持我的目的,希望把这个端玩好。当然前路漫漫,用爱发电!里面的东西太多了慢慢来吧。真希望有人可以相互交流交流!!
代码查询 https://mxdweb.com/
问题解决汇总
日期:2022 03- 24
1.解决闪退问题参照 https://docs.qq.com/doc/DZmlnd1BSQnd2S0ti
2.java.lang.NumberFormatException: For input string: "2203232321"
时间大于int表示的最大值2147483647 也就是21年47月48日36:47 实际并不存在 修复:先转成long,然后强转成int
方法地址:tools.DateUtil#getTime(long)
3.修复新手转职飞侠脚本里面是+敏捷
0324
代码中是这个字段
永远都是0 从而导致这个判断错误,我修复了所以是false
只是把获取的地方改一下,该读还是要读的
0510 想修复打怪任务增加怪物
最终找到了是任务没有初始化,导致任务的怪物没有被添加到任务状态中 server.quest.MapleQuest.initQuests
PreparedStatement ps = con.prepareStatement("SELECT * FROM wz_questdata");
PreparedStatement psr = con.prepareStatement("SELECT * FROM wz_questreqdata WHERE questid = ?");
PreparedStatement psa = con.prepareStatement("SELECT * FROM wz_questactdata WHERE questid = ?");
PreparedStatement pss = con.prepareStatement("SELECT * FROM wz_questactskilldata WHERE uniqueid = ?");//需要的技能
PreparedStatement psq = con.prepareStatement("SELECT * FROM wz_questactquestdata WHERE uniqueid = ?"); //应该是自己写的补丁数据库
PreparedStatement psi = con.prepareStatement("SELECT * FROM wz_questactitemdata WHERE uniqueid = ?");//通过uniqueid来找需要的item
PreparedStatement psp = con.prepareStatement("SELECT * FROM wz_questpartydata WHERE questid = ?");//组队任务
这些表都没有,只能从079那边拿过来,但是数据需要自己填充的。。。怪不得除了id全是空的。
navicat同步结构和数据
需要单独添加一个灯泡字段
2022-05-11 00:17:59.242
Send SHOW_STATUS_INFO [0061] (11) Recv to : 飞飞
61 00 01 8D 0A 01 03 00 30 30 34
已经可以正常的发送了,但是客户端确实没有更新到数据,可能是这个封包和079的已经不一样了,需要修复这个
0511
比较了swordie176的源码发现任务id从short改成了int,发现就可以了,任务可以正常完成了
任务相关表信息
# 任务信息
select * from wz_questactdata where questid = 2701
# 任务需要和获取的东西
select * from wz_questactdata where questid = 2089
# 和actdata uniqueid 关联 物品信息
select * from wz_questactitemdata where uniqueid in (select uniqueid from wz_questactdata where questid = 2089 and name = 'item')
# 和任务关联的任务
select * from wz_questactquestdata where QUEST = 2100
# 和任务关联的技能
select * from wz_questactskilldata where uniqueid = 218
# 任务的状态
SELECT * FROM queststatus WHERE QUEST = 2701
# 任务信息
select * from questinfo where quest = 2701
# 任务怪物状态
select * from queststatusmobs
绿蘑菇任务是2701,相关联的信息为
# request info
INSERT INTO `chms`.`wz_questdata`(`questid`, `name`, `autoStart`, `autoPreComplete`, `viewMedalItem`, `selectedSkillID`, `blocked`, `autoAccept`, `autoComplete`, `selfStart`) VALUES (2701, '绿蘑菇通缉牌', 0, 0, 0, 0, 0, 0, 0, 0);
# request
INSERT INTO `chms`.`wz_questreqdata`(`id`, `questid`, `name`, `type`, `stringStore`, `intStoresFirst`, `intStoresSecond`) VALUES (22728, 2701, 'mob', 1, '0', '1110100', '20');
#act data
INSERT INTO `chms`.`wz_questactdata`(`id`, `questid`, `name`, `type`, `intStore`, `applicableJobs`, `uniqueid`) VALUES (7757, 2701, 'exp', 1, 434, '', -1);
INSERT INTO `chms`.`wz_questactdata`(`id`, `questid`, `name`, `type`, `intStore`, `applicableJobs`, `uniqueid`) VALUES (7758, 2701, 'item', 1, 0, '', 2001);
# item data
INSERT INTO `chms`.`wz_questactitemdata`(`id`, `itemid`, `count`, `period`, `gender`, `job`, `jobEx`, `prop`, `uniqueid`) VALUES (9101, 1032003, 1, 0, 2, -1, -1, -2, 2001);
对应的就是这个
最后完成任务
总结:
其实就是把questid 改成int传就好了。剩下和079的一样。修复任务绝对是吃力不讨好的事情
0512 修复五转任务 这里涉及到脚本任务的完成,但是脚本任务完成原本的代码实际上并没有任何逻辑,所以要完成任务还是需要wz的任务进行支撑。 一个合理的猜测是脚本任务只能是马上完成的?不能是有过程的?
格兰蒂斯的神秘石任务 数据库添加1463任务的数据即可
INSERT INTO `chms`.`wz_questdata`(`questid`, `name`, `autoStart`, `autoPreComplete`, `viewMedalItem`, `selectedSkillID`, `blocked`, `autoAccept`, `autoComplete`, `selfStart`) VALUES (1463, '格兰蒂斯的神秘石', 0, 0, 0, 0, 0, 0, 0, 0);
# 我添加的是简单老麦的信息
INSERT INTO `chms`.`wz_questreqdata`(`id`, `questid`, `name`, `type`, `stringStore`, `intStoresFirst`, `intStoresSecond`) VALUES (22729, 1463, 'mob', 1, '0', '8880010', '1');
绯红的神秘石 次元之镜加一个废弃营地 脚本是直接完成了任务,说明这个估计不好修复,我也跳过了 server.maps.MapleSlideMenu.SlideMenu5.TownTeleport 最后一行加 bus(24, "万神殿", 400000000, 0), but(25, "废弃营地", 105300000, 0);
然后就是获取神秘球的任务 questId = 1466 添加信息
INSERT INTO chms
.wz_questreqdata
(id
, questid
, name
, type
, stringStore
, intStoresFirst
, intStoresSecond
) VALUES (null, 1466, 'mob', 1, '0', '8641000', '10');
INSERT INTO chms
.wz_questdata
(questid
, name
, autoStart
, autoPreComplete
, viewMedalItem
, selectedSkillID
, blocked
, autoAccept
, autoComplete
, selfStart
) VALUES (1466, '另一种力量,神秘力量', 0, 0, 0, 0, 0, 0, 0, 0);
0513 今天看代码发现一个问题,服务端是有处理这个五转获取神秘石任务的,这里代码有问题。直接把这一段删了就好了
server.maps.MapleMap.killMonster(server.life.MapleMonster, client.MapleCharacter, boolean, boolean, byte, int)
。。。
} else if (monster.getId() == 9101083 || monster.getId() == 8880000 || monster.getId() == 8880002) { //麦格纳斯
if (chr.getQuestStatus(1463) == 1) {
chr.dropMessage(-1, "由于麦格纳斯死亡时施放出的能量,不再受到古瓦洛的力量的影响。");
MapleQuestStatus quest = chr.getQuest(MapleQuest.getInstance(1463));
quest.setCustomData("001");
chr.updateQuest(quest);
}
}
把昨天限时任务修复 参考swordie
public static OutPacket setQuestTime(List<Triple<Integer, FileTime, FileTime>> questTimes) {
OutPacket outPacket = new OutPacket(OutHeader.SET_QUEST_TIME);
outPacket.encodeByte(questTimes.size());
for(Triple<Integer, FileTime, FileTime> times : questTimes) {
outPacket.encodeInt(times.getLeft());
outPacket.encodeFT(times.getMiddle());
outPacket.encodeFT(times.getRight());
}
return outPacket;
}
改成如下,传入的参数改成秒,脚本默认传入的是毫秒
/**
* 更新限时任务
* @param quest
* @param time second 需要改脚本传秒数
* @return
*/
public static byte[] startQuestTimeLimit(int quest, int time) {
if (ServerConfig.DEBUG_MODE) {
log.trace("调用限时任务");
}
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.UPDATE_QUEST_INFO.getValue());
mplew.write(1);
mplew.writeInt(quest);
LocalDateTime now = LocalDateTime.now();
LocalDateTime end = now.plusSeconds(time);
FileTime start = FileTime.fromDate(now);
FileTime endTime = FileTime.fromDate(end);
// outPacket.encodeInt(getHighDateTime());
// outPacket.encodeInt(getLowDateTime());
FileTime.encode(mplew, start);
FileTime.encode(mplew, endTime);
return mplew.getPacket();
}
// FileTime方法
public static void encode(MaplePacketLittleEndianWriter mplew, FileTime fileTime) {
mplew.writeInt(fileTime.getHighDateTime());
mplew.writeInt(fileTime.getLowDateTime());
}
0514
学习ida,我也不是很会,也是新手,就来简单学习一下: 在swordie代码中可以看到outbound他都有标注,
// CUserLocal::OnPacket
EMOTION(685),
在我们maplesotry143找到这个包头
// handling.opcode.SendPacketOpcode USER_EMOTION_LOCAL(0x2d4),
02d4换算出来就是724
然后在143的idb文件找到这个CUserLocal::OnPacket
int __thiscall CUserLocal::OnPacket(_DWORD *this, int a2, LPCWSTR lpWideCharStr)
{
int result; // eax
int v4; // ecx
char v5; // [esp-1Ch] [ebp-20h]
int v6; // [esp-18h] [ebp-1Ch]
char v7; // [esp-14h] [ebp-18h]
int v8; // [esp-10h] [ebp-14h]
int v9; // [esp-Ch] [ebp-10h]
int v10; // [esp-8h] [ebp-Ch]
int v11; // [esp-4h] [ebp-8h]
result = a2 - 724;
switch ( a2 )
{
case 724:
// 这里的名字是我改的
result = USER_EMOTION_LOCAL(this, lpWideCharStr);
int __thiscall USER_EMOTION_LOCAL(_DWORD *this, _DWORD *a1)
{
_DWORD *v2; // ST18_4
int *v3; // eax
int *v4; // ebx
int v5; // eax
int v6; // esi
unsigned __int8 v7; // al
v2 = this;
CInPacket::Decode4(a1);
v4 = v3;
CInPacket::Decode4(a1);
v6 = v5;
CInPacket::Decode1(a1);
sub_1B27EB0(v2, v4, v6, v7);
return sub_C2D3B0(1);
}
可以看到ida需要两个int 一个 byte,我们143服务端也是这样写好的
public static byte[] getDirectionFacialExpression(int expression, int duration) {
log.trace("调用");
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.USER_EMOTION_LOCAL.getValue());
mplew.writeInt(expression);
mplew.writeInt(duration);
mplew.write(0);
return mplew.getPacket();
}
这样就对应上了,这就是一个简单的例子,具体什么意思我也不懂,需要再研究研究
0518
在重构job和skill相关的代码发现好多技能都是两个技能id,但是是同名的,感觉有点离谱,难道是技改了?比如下面这个
0520
重构攻击的发现里面有079的技能判定删掉了,侠盗的金钱攻击
主要拆分攻击不同的攻击类型 近战、远程、魔法攻击,不同的职业需要单独实现的功能
解析包体
是否显示暴击
控制被动攻击、例如斗气掉点数(原来代码就是写在近战攻击的处理里面)
攻击类
总结:
主要解耦成以上这几个方面,远程和魔法攻击也是类似,先把所有职业都解耦出来,然后打算再一个一个的修复。后面这几个attack的不同状态,会麻烦一些,而且看完代码发现好多都没有实现的。所以还是慢慢来咯。
还要把状态相关的部分也了解,不然技能感觉也不好修复
主要就三个维度:1.伤害 ,2.不同职业、职业群的效果 3.不同的状态。 职业和状态可能是多对多?
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。