- 浏览: 167210 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
兰斯洛特1987:
顶!!!!谢谢分享.最近我也在研究这玩意...
Java语言的Hook实现 -
pu02203:
我把Confidant.jar, 丢进去eclipse, 里面 ...
重磅推出诛仙辅助软件第二波:Java版按键精灵 -
泣血端午:
Calculagraph 这是哪个类啊?
A星算法 -
haitaohehe:
我使用的是jstl1.0 可是在使用<c:set va ...
JSTL1.0和JSTL1.1的区别 -
micheal19840929:
学习楼主,我也测试一下~看看兼容性吧。lanlanzhilia ...
手机版飞鸽传书:无线牵
前言:上次推出诛仙答题辅助软件用起来不错(想上十名榜不难,YY下),不过在后来我自己使用过程中发现程序存在BUG,就是启用后,如果你不是按小键盘的12345而按鼠标右键,程序就不能使用了,应该是进入逻辑循环,根本原因是我的程序架构上存在问题,所以针对上次的教训本次推出的第二波辅助软件采用全新的架构:“模式架构”(名字要响亮,:)),这种模式能从根本解决之前的那类逻辑问题,而且能够很明朗的进行业务分析。
回到正题,本次推出的辅助软件是一个精简的按键精灵,不过麻雀虽小,五脏俱全,基本的功能还是有的,虽然没有可视化,但并不影响使用(使用XML作为脚本文件,可以很方便进行修改)。先说应用吧,现在的玩诛仙的人很多都会挂机,那么挂机就要用的按键精灵。一般人都使用网上已有的那个精灵,然而说不定哪天老池来一次精灵封杀,到时给你一个封号几万小时,你哭都来不及。所以还是自力更生,才能丰衣足食啊。
本次推出的精灵主要功能有:
1、支持鼠标、键盘按键记录
2、支持脚本生成及脚本导入
3、只支持单个计时器(不知道多个计时器有没必要)
4、只记录鼠标的左键事件,并且只记录鼠标click事件,不记录拖动事件
5、只记录键盘按键的按下事件
6、保存脚本的时间以秒为单位(带一位小数)
软件的使用方法如下:
1、启动run.bat,系统打开命令提示符并运行软件,开始是进行菜单选择(录制模式与模拟模式),可以按F12退出软件
2、如果选择录制模式则系统开始录制你的鼠标及键盘操作(具体参考功能列表),这时可以按F12停止录制并返回菜单选择
3、退出录制模式后,软件会将你的本次操作列表在软件目录下保存成脚本文件,名字为script.xml
4、如果选择模拟模式,软件会在它的目录下导入script.xml脚本文件并开始循环模拟操作列表中的操作。可以按F12停止模拟并返回菜单选择。
进入正文,先来看看我们的项目架构,看图:
因为本软件涉及的类比较多,所以对于之前有讲过的类(包括KeyboardHookEventListener.java、MouseHookEventListener.java、Task.java、TaskThread.java)这里就不做详述了,需要的可以参考我之前的文章:Java语言的Hook实现。
下面我们先来看下所谓的“模式架构”:
Mode.java
package beta01; public interface Mode { public static final int F_12=123; public static final int NUM_1=97; public static final int NUM_2=98; public void start(); public void doPress(int keyNum); public void doReleased(int keyNum); public void doLeftPressed(int x,int y); public void doLeftReleased(int x,int y); public void doRightPressed(int x,int y); public void doRightReleased(int x,int y); public void doMiddlePressed(int x,int y); public void doMiddleReleased(int x,int y); }
很简单吧,只要每一种子模式继承了它,就不会存在之前的逻辑问题了,呵呵。软件包括三种模式:菜单模式、录制模式及模拟模式。这里我全部都采用匿名类进行继承,后面会进行介绍。先来看看操作类:
Operation.java
package module; import java.awt.Point; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.math.BigDecimal; public class Operation implements Externalizable { private static final long serialVersionUID = 1L; public static final int MODE_KEYBOARD=1; public static final int MODE_MOUSE=2; public static final int MODE_UNKNOWN=3; private Integer instruction = null; //键盘按键 private Point point; //鼠标左击位置 private Long delay; //延迟时间 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { decode(in.readLine()); } public void writeExternal(ObjectOutput out) throws IOException { out.writeBytes(this.encode()); out.writeChar('\n'); } public Long getDelay() { return delay; } public void setDelay(Long delay) { this.delay = delay; } public Integer getInstruction() { return instruction; } public void setInstruction(Integer instruction) { this.instruction = instruction; } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } @Override public String toString() { return encode(); } /** * 将字符串解码成操作实体 * @param info */ public void decode(String info) { if (info != null && info.length() != 0) { String str[] = info.split("@"); if (str.length == 2) { this.delay = (long)(round((Double.parseDouble(str[1].trim())*1000),0)); String[] sstr = str[0].split(","); if (sstr.length == 2) { this.point = new Point(Integer.parseInt(sstr[0].trim()), Integer.parseInt(sstr[1].trim())); } else if (sstr.length == 1) { this.instruction = Integer.parseInt(sstr[0].trim()); } else { this.delay = null; } } } } /** * 对操作类进行编码成字符串,方便保存 * @return */ public String encode() { if (instruction == null) { return point.x + "," + point.y + "@" + round((double)delay/1000,1); } else { return instruction + "@" + round((double)delay/1000,1); } } public int getMode() { if(this.instruction==null&&this.point!=null) { return MODE_MOUSE; } else if(this.instruction!=null&&this.point==null) { return MODE_KEYBOARD; } return MODE_UNKNOWN; } /** * * 提供精确的小数位四舍五入处理。 * * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 * */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } }
主要负责记录每一次操作,包括鼠标及键盘操作,鼠标记录位置,键盘记录键码,两种都有一个延迟时间,注意延迟时间是相对时间,即本次操作的延迟时间是相对于上次操作而言,如第一个操作的延迟是1s,第二个操作的延迟是2.1s,那么第一个操作是在启动模拟模式后1秒后执行,第二个操作是在第一个操作执行完毕后的2.1秒过后执行。
InstructionTask.java:
package module; import java.awt.AWTException; import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; import core.Task; /** * 执行指令的任务 * @author Micheal * */ public class InstructionTask implements Task { private static Robot robot; static { try { robot=new Robot(); } catch (AWTException e) { e.printStackTrace(); } } private Integer instruction; private Point point; public InstructionTask(){} public InstructionTask(Integer instruction) { this.instruction=instruction; this.point=null; } public InstructionTask(Point point) { this.point=point; this.instruction=null; } public Integer getInstruction() { return instruction; } public void setInstruction(Integer instruction) { this.instruction = instruction; this.point=null; } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; this.instruction=null; } /** * 执行任务 */ public void perform() { // System.out.println("perform:"+toString()); if(this.instruction!=null) { robot.keyPress(instruction); robot.keyRelease(instruction); } else if(this.point!=null) { robot.mouseMove(point.x,point.y); robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); } else { System.out.println("!警告:非可执行操作!"); } } @Override public String toString() { if(this.instruction!=null) { return String.valueOf(this.instruction); } else if(this.point!=null) { return this.point.toString(); } else { return "nothing"; } } }
这里要说明下,由于我是准备支持多计时器的,所以才会用到任务列表及任务线程的问题。如果只是单单支持一个的话那么直接使用java.util.Timer定时器就可以了。
计时器Calculagraph.java:
package module; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import core.TaskThread; /** * 计时器 * @author Micheal * 线程执行,当系统时间达到操作延迟时间要求时,将操作指令传入执行器队列中 * */ public class Calculagraph extends Thread implements Externalizable { private static final long serialVersionUID = 1L; private static TaskThread executive; private String title; private List<Operation> operations; private boolean runnable=true; private Timer timer; public Calculagraph(){} public Calculagraph(String title) { this.title=title; } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.title=in.readUTF(); int count=in.readInt(); in.readChar(); operations=new LinkedList<Operation>(); for(int i=0;i<count;i++) { Operation operation=new Operation(); operation.readExternal(in); operations.add(operation); } } public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(title); out.writeInt(operations.size()); out.writeChar('\n'); for(Operation op:operations) { op.writeExternal(out); } } @Override public synchronized void start() { super.start(); executive=TaskThread.getInstance(); executive.start(); } @Override public void run() { Label:while(runnable) { if(timer==null) { timer=new Timer(false); //创建非daemon线程 } int count=1; for(Operation op:operations) { final InstructionTask task=new InstructionTask(); switch(op.getMode()) { case Operation.MODE_KEYBOARD: task.setInstruction(op.getInstruction()); break; case Operation.MODE_MOUSE: task.setPoint(op.getPoint()); break; default: continue; } timer.schedule(new TimerTask(){ @Override public void run() { if(runnable==false) { synchronized(Calculagraph.this){ Calculagraph.this.notify(); } return; } executive.addTask(task); synchronized(Calculagraph.this){ Calculagraph.this.notify(); } }},op.getDelay()); try { synchronized(this) { this.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("执行操作:"+count+++"/"+operations.size()+"-->"+op); if(runnable==false) break Label; } } timer.cancel(); executive.close(); executive=null; System.out.println("--计时器已关闭--"); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public synchronized void close() { this.runnable=false; this.notify(); } public List<Operation> getOperations() { return operations; } public void setOperations(List<Operation> operations) { this.operations = operations; } public void addOperation(Operation operation) { if(this.operations==null) { this.operations=new LinkedList<Operation>(); } this.operations.add(operation); } }
两大精华之一,实现对操作的模拟所在,使用了java多线程的wait,notify机制;
录制器TempRecorder.java:
package beta01; import java.awt.Point; import java.util.Date; import java.util.LinkedList; import java.util.List; import module.Operation; public class TempRecorder { private static Long latestRecordTime; //上次记录时间 private static List<Operation> operations=new LinkedList<Operation>(); private static Point pressPoint=new Point(-65525,-65525); private static Point releasePoint=new Point(-65525,-65525); public static void start(){ /*清空数据*/ latestRecordTime=new Date().getTime(); operations=new LinkedList<Operation>(); } public static void doPress(int keyNum){ Long currentTime=new Date().getTime(); Long delay=currentTime-latestRecordTime; Operation operation=new Operation(); operation.setInstruction(keyNum); operation.setDelay(delay); latestRecordTime=currentTime; operations.add(operation); System.out.println("记录操作:"+operation); } public static void doReleased(int keyNum) {} public static void doLeftPressed(int x, int y) { pressPoint.setLocation(x, y); } public static void doLeftReleased(int x, int y) { releasePoint.setLocation(x, y); /* * 如果是click(press与release在同一个位置)则记录 */ if(releasePoint.equals(pressPoint)) { Long currentTime=new Date().getTime(); Long delay=currentTime-latestRecordTime; Operation operation=new Operation(); operation.setPoint(new Point(pressPoint.x,pressPoint.y)); operation.setDelay(delay); latestRecordTime=currentTime; operations.add(operation); System.out.println("记录操作:"+operation); } //清空数据 clearPoint(pressPoint); clearPoint(releasePoint); } private static void clearPoint(Point point) { point.setLocation(-65525,-65525); } public static List<Operation> getOperations() { return operations; } }
细心的读者可能看到上面我的图中有个Recorder.java类,那个是暂时废弃的,暂时使用这一个。
Config.java:
package beta02; import java.io.File; import java.io.IOException; import org.apache.xmlbeans.XmlException; import org.dom4j.DocumentException; import core.XMLFormater; import script.CalculagraphDocument; import module.Calculagraph; import module.Operation; public class Config { private static final String FILE_PATH = "script.xml"; /** * 导入脚本 * @param calculagraph */ public static void loadConfig(Calculagraph calculagraph) { File file = new File(FILE_PATH); try { CalculagraphDocument doc = CalculagraphDocument.Factory.parse(file); calculagraph.setTitle(doc.getCalculagraph().getTitle()); int operationSize = doc.getCalculagraph().getOperations() .sizeOfOperationArray(); for (int i = 0; i < operationSize; i++) { Operation operation = new Operation(); operation.decode(doc.getCalculagraph().getOperations() .getOperationArray(i)); calculagraph.addOperation(operation); } } catch (XmlException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 生成脚本 * @param calculagraph */ public static void saveConfig(Calculagraph calculagraph) { File file = new File(FILE_PATH); try { file.createNewFile(); CalculagraphDocument doc = CalculagraphDocument.Factory .newInstance(); if (calculagraph != null) { doc.addNewCalculagraph().setTitle(calculagraph.getTitle()); if (calculagraph.getOperations() != null) { doc.getCalculagraph().addNewOperations(); for (Operation op : calculagraph.getOperations()) { doc.getCalculagraph().getOperations().addOperation( op.encode()); } } } doc.save(file); XMLFormater.format(file); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } } }
为了支持XML文件保存与读取,我使用了XMLBean技术来实现,很方便的说,不了解的百度下。
XMLFormator.java:
package core; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class XMLFormater { public static void format(File file) throws DocumentException, IOException { SAXReader reader = new SAXReader(); Document doc= (Document)reader.read(file); OutputFormat of = OutputFormat.createPrettyPrint(); of.setIndent(true); of.setNewlines(true); of.setLineSeparator("\r\n"); Writer fileWriter=new FileWriter(file); XMLWriter xmlWriter=new XMLWriter(fileWriter,of); xmlWriter.write(doc); xmlWriter.close(); } }
实现对xml文件进行格式化。
Main.java:
package beta02; import module.Calculagraph; import org.sf.feeling.swt.win32.extension.hook.Hook; import beta01.Mode; import beta01.TempRecorder; import core.KeyboardHookEventListener; import core.MouseHookEventListener; public class Main { private static Mode menuMode; private static Mode recordMode; private static Mode imitateMode; private static Mode currentMode; private static Calculagraph calculagraph; private static MouseHookEventListener mouseListener=null; private static KeyboardHookEventListener keyboardListener=null; /** * @param args */ public static void main(String[] args) { keyboardListener=new KeyboardHookEventListener(){ @Override public void doPress(int keyNum) { if(currentMode!=null) { currentMode.doPress(keyNum); } } @Override public void doReleased(int keyNum) { if(currentMode!=null) { currentMode.doReleased(keyNum); } } }; mouseListener=new MouseHookEventListener(){ @Override protected void doLeftPressed(int x, int y) { if(currentMode!=null) { currentMode.doLeftPressed(x, y); } } @Override protected void doLeftReleased(int x, int y) { if(currentMode!=null) { currentMode.doLeftReleased(x, y); } } @Override protected void doMiddlePressed(int x, int y) { if(currentMode!=null) { currentMode.doMiddlePressed(x, y); } } @Override protected void doMiddleReleased(int x, int y) { if(currentMode!=null) { currentMode.doMiddleReleased(x, y); } } @Override protected void doRightPressed(int x, int y) { if(currentMode!=null) { currentMode.doRightPressed(x, y); } } @Override protected void doRightReleased(int x, int y) { if(currentMode!=null) { currentMode.doRightReleased(x, y); } } }; menuMode=new Mode(){ public void start() { System.out.println("请选择模式:"); System.out.println("NUM1:记录模式"); System.out.println("NUM2:模拟模式"); System.out.println("F12:退出系统"); } public void doPress(int keyNum) { switch(keyNum) { case Mode.NUM_1: currentMode=recordMode; recordMode.start(); break; case Mode.NUM_2: currentMode=imitateMode; imitateMode.start(); break; case Mode.F_12: System.out.println("--退出系统--"); System.exit(0); break; default: } } public void doReleased(int keyNum) {} public void doLeftPressed(int x, int y) {} public void doLeftReleased(int x, int y) {} public void doMiddlePressed(int x, int y) {} public void doMiddleReleased(int x, int y) {} public void doRightPressed(int x, int y) {} public void doRightReleased(int x, int y) {} }; recordMode=new Mode(){ public void doPress(int keyNum) { if(keyNum==Mode.F_12) { calculagraph=new Calculagraph("Imitator"); calculagraph.setOperations(TempRecorder.getOperations()); Config.saveConfig(calculagraph); calculagraph=null; System.out.println("--记录模式已关闭--"); currentMode=menuMode; menuMode.start(); return; } TempRecorder.doPress(keyNum); } public void doReleased(int keyNum) { TempRecorder.doReleased(keyNum); } public void start() { TempRecorder.start(); System.out.println("记录模式已启动,系统正在记录您的操作..."); } public void doLeftPressed(int x, int y) { TempRecorder.doLeftPressed(x, y); } public void doLeftReleased(int x, int y) { TempRecorder.doLeftReleased(x, y); } public void doMiddlePressed(int x, int y) {} public void doMiddleReleased(int x, int y) {} public void doRightPressed(int x, int y) {} public void doRightReleased(int x, int y) {} }; imitateMode=new Mode(){ public void doPress(int keyNum) { if(keyNum==Mode.F_12) { calculagraph.close(); calculagraph=null; System.out.println("--模拟模式已关闭--"); currentMode=menuMode; menuMode.start(); } } public void doReleased(int keyNum) {} public void start() { if(calculagraph==null) { calculagraph=new Calculagraph("Imitator"); } Config.loadConfig(calculagraph); calculagraph.start(); System.out.println("模拟模式已启动,系统正在模拟您的操作..."); } public void doLeftPressed(int x, int y) {} public void doLeftReleased(int x, int y) {} public void doMiddlePressed(int x, int y) {} public void doMiddleReleased(int x, int y) {} public void doRightPressed(int x, int y) {} public void doRightReleased(int x, int y) {} }; Hook.MOUSE.addListener(mouseListener); Hook.KEYBOARD.addListener(keyboardListener); Hook.MOUSE.install(); Hook.KEYBOARD.install(); currentMode=menuMode; menuMode.start(); } }
使用设计模式中的模板模式,负责程序调度。
最后生成的脚本文件如下:
<?xml version="1.0" encoding="UTF-8"?> <calculagraph> <title>Imitator</title> <operations> <operation>710,918@2.0</operation>//@后面是延迟时间 <operation>975,888@0.4</operation> <operation>841,920@0.4</operation> <operation>68@1.1</operation> <operation>71@0.3</operation> <operation>861,915@0.5</operation> </operations> </calculagraph>
附件是我打包好的程序,欢迎使用,:)
- Confidant.rar (4.2 MB)
- 下载次数: 191
评论
都是org.apache.xmlbeans的东西
呵呵,也用不了多少时间,主要是其中的一些小模块在以前的开发过程中已经编写出来了,这里只是直接套用一下而已
发表评论
-
快速开方算法比较
2010-08-18 17:34 1389快速开方算法比较: public class Test { ... -
Java父线程与子线程
2010-06-12 12:49 2759问:在父线程中New了一个子线程,想在停止父线程时也停止子线程 ... -
反射在设计模式中的应用
2010-06-08 10:52 736利用设计模式可以使我 ... -
Reader和InputStream的区别
2010-05-28 13:21 1279Reader支持16位的Unicode字符输出,InputSt ... -
[原创]多线程之队列式执行任务
2010-04-29 10:24 966前言:最近做的一个项目正好要用到多线程,而且要实现 ... -
java内存的思考与总结
2010-02-10 16:13 01. java中堆与栈 在Java程 ... -
关于switch语句
2010-02-10 16:10 813switch语句在一定程度上是有动态跳转(函数指针就是一种动态 ... -
代码优化之-优化除法
2010-02-09 13:57 2516说明:文章中的很多数据可能在新的CPU或不同的CPU或不同的系 ... -
Supported Encodings
2010-02-09 13:41 918The classes java.io.InputStream ... -
应用JAD批量反编译CLASS文件
2010-02-09 12:31 817反编译别人的程序是不对的,但是有时候由于某种原因,不得不反编译 ... -
数组快速复制
2010-02-08 15:33 708data[0] = 0 ; int len = 1 ; i ... -
深刻理解Java编程的7个例子
2010-01-14 10:13 6421. 阅读下列代码回答问 ... -
原子变量(AtomicLong, AtomicInteger, AtomicReference)
2009-11-06 09:30 3322J2SE 5.0提供了一组atomic class来帮助我们简 ... -
Java语言的Hook实现
2009-08-25 17:39 11382引言:最近在玩完美时 ...
相关推荐
1. **Java编程语言**:Java是一种跨平台的面向对象的编程语言,它以其高效、稳定和安全性在服务器端应用中广泛使用。梦幻诛仙的后台系统选择Java作为开发语言,保证了系统的可移植性和安全性。 2. **网络验证机制**...
本后台适合多数比例服、转生服、后台服等等。后端采用SpringBoot + Mybatis,前端采用Vue + elementui框架,并使用webpack打包,前后端完全分离,并采用session校验,完美防刷。
《Authorware 7.0与"诛仙"游戏源代码解析》 Authorware 7.0,是一款由Macromedia公司开发的图标导向型多媒体创作工具,它以其强大的交互性和直观的操作界面,深受广大程序员和多媒体设计师的喜爱。在这个标题为...
《诛仙3人物管理器》是一款专为诛仙游戏爱好者设计的工具,它集成了人物职业编辑和游戏内充值管理等功能,旨在为玩家提供更加便捷的游戏体验。在深入理解这款管理器之前,我们需要先了解一些基础概念和技术背景。 ...
《诛仙VIP奖励编辑工具》是一款专为网络游戏《诛仙》设计的辅助工具,它集成了游戏内的VIP奖励编辑和商城管理功能,旨在为玩家提供更便捷的游戏体验。这款工具在网单(网络单机)环境中同样表现出色,能够帮助玩家更...
因此,一位已经脱坑的《诛仙》玩家开发了《网游诛仙分金鉴挖宝坐标计算器》软件,旨在帮助玩家更高效地寻宝,充分体现了玩家的创造力和对游戏的深刻理解。 《网游诛仙分金鉴挖宝坐标计算器》的核心功能是坐标计算。...
【梦幻诛仙最新后台_manpy7_梦幻诛仙后台_梦幻诛仙_梦诛后台版_MHZX新版后台By多资源】是一个针对网络游戏《梦幻诛仙》的后台管理系统。这个系统由开发者manpy7更新并提供了更多的功能,适用于对游戏进行管理和维护...
距离计算是源码中的第二个实用功能。在任何游戏中,计算两个对象之间的距离对于实现自动化操作至关重要。例如,自动寻路功能需要计算玩家角色与目的地之间的距离,而自动战斗则依赖于角色与敌人的距离判断。源码提供...
1. `gsxdb.jar.filepart`:这可能是一个部分下载的Java ARchive (JAR) 文件,通常包含Java类文件和其他资源,可能是用于数据库连接或游戏逻辑的辅助工具。 2. `bg.gif`:背景图像文件,用于美化GM后台的用户界面。 ...
2. **面向对象**:Java是一种面向对象的语言,它支持类、对象、继承、封装和多态等面向对象特性。这使得程序设计更加模块化,易于维护和扩展。 3. **分布式计算**:Java内置了网络通信功能,支持TCP/IP协议,方便...
同时,保持软件及数据库的更新,确保与游戏服务器的兼容性。 《诛仙游戏账号管理工具》的出现,极大地简化了游戏账号的管理过程,使玩家能够更加专注于游戏本身,享受游戏带来的乐趣,而不用担忧账号安全问题。无论...
《诛仙3单机el编辑器》是一款专为《诛仙3》单机版设计的游戏辅助工具,旨在帮助玩家更方便地对游戏内的各种元素进行个性化调整。通过这款编辑器,用户可以对游戏中的NPC(非玩家角色)、物品以及出售列表进行编辑,...
2. **数据库设置**:《诛仙》的游戏数据存储在数据库中,你需要创建数据库,导入游戏的初始数据,设置用户权限,并确保数据库服务正常运行。 3. **服务端程序安装**:获取《诛仙》的服务端程序,这可能需要从官方...
请将多开器复制到诛仙安装目录下的element文夹里运行,本多开器支持不同区服的多开,本版本仅支持四开.游戏,开启后多开器可以关闭,无限多开版本为内部定制版本。资源作者:。@易语言源码大全。资源界面:。资源下载...
总的来说,这款由C#编写的《诛仙》技能天赋模拟器,不仅为玩家提供了便利的游戏辅助工具,还促进了玩家之间的交流与学习。它以实际游戏数据为基础,结合C#的强大计算能力,使得玩家在游戏之外也能享受到策略规划的...
梦幻诛仙物品id大全,一键端使用对照物品id,可添加到商城或者后台发送列表。 丹青11职业版本 比较全的列表。
易语言写完美游戏诛仙辅助,方便学习参考!
诛仙源码
2. **论坛风格/模板**:论坛模板决定了论坛的外观和布局,用户可以根据自己的需求和喜好选择或定制模板,改变论坛的视觉效果。 3. **网页模版的结构**:一般包括HTML(页面结构)、CSS(样式控制)、JavaScript...