`
micheal19840929
  • 浏览: 167269 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

重磅推出诛仙辅助软件第二波:Java版按键精灵

    博客分类:
  • J2SE
阅读更多

前言:上次推出诛仙答题辅助软件用起来不错(想上十名榜不难,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>

 

 

 附件是我打包好的程序,欢迎使用,:)

4
0
分享到:
评论
4 楼 pu02203 2012-03-04  
我把Confidant.jar, 丢进去eclipse, 里面怎么找不到任何java檔
都是org.apache.xmlbeans的东西
3 楼 micheal19840929 2009-09-17  
fengque531 写道
啊。。。。。LZ你花了多长时间做这个东西?

呵呵,也用不了多少时间,主要是其中的一些小模块在以前的开发过程中已经编写出来了,这里只是直接套用一下而已
2 楼 fengque531 2009-09-17  
啊。。。。。LZ你花了多长时间做这个东西?
1 楼 songlipeng 2009-09-17  
牛人。。java也能做外挂。。。

相关推荐

    java版后台_梦幻诛仙验证_梦幻诛仙java_梦诛java版全功能后台_梦诛java_clothpof_

    1. **Java编程语言**:Java是一种跨平台的面向对象的编程语言,它以其高效、稳定和安全性在服务器端应用中广泛使用。梦幻诛仙的后台系统选择Java作为开发语言,保证了系统的可移植性和安全性。 2. **网络验证机制**...

    梦幻诛仙java版完美后台

    本后台适合多数比例服、转生服、后台服等等。后端采用SpringBoot + Mybatis,前端采用Vue + elementui框架,并使用webpack打包,前后端完全分离,并采用session校验,完美防刷。

    authorware 7.0 诛仙 源代码

    《Authorware 7.0与"诛仙"游戏源代码解析》 Authorware 7.0,是一款由Macromedia公司开发的图标导向型多媒体创作工具,它以其强大的交互性和直观的操作界面,深受广大程序员和多媒体设计师的喜爱。在这个标题为...

    诛仙3人物管理器_诛仙人物管理_诛仙3人物管理器_诛仙人物_诛仙_

    《诛仙3人物管理器》是一款专为诛仙游戏爱好者设计的工具,它集成了人物职业编辑和游戏内充值管理等功能,旨在为玩家提供更加便捷的游戏体验。在深入理解这款管理器之前,我们需要先了解一些基础概念和技术背景。 ...

    诛仙VIP奖励编辑工具_诛仙编辑_诛仙商城工具_网单_诛仙_诛仙工具_

    《诛仙VIP奖励编辑工具》是一款专为网络游戏《诛仙》设计的辅助工具,它集成了游戏内的VIP奖励编辑和商城管理功能,旨在为玩家提供更便捷的游戏体验。这款工具在网单(网络单机)环境中同样表现出色,能够帮助玩家更...

    网游诛仙分金鉴挖宝坐标计算器

    因此,一位已经脱坑的《诛仙》玩家开发了《网游诛仙分金鉴挖宝坐标计算器》软件,旨在帮助玩家更高效地寻宝,充分体现了玩家的创造力和对游戏的深刻理解。 《网游诛仙分金鉴挖宝坐标计算器》的核心功能是坐标计算。...

    梦幻诛仙最新后台_manpy7_梦幻诛仙后台_梦幻诛仙_梦诛后台版_MHZX新版后台By多资源_

    【梦幻诛仙最新后台_manpy7_梦幻诛仙后台_梦幻诛仙_梦诛后台版_MHZX新版后台By多资源】是一个针对网络游戏《梦幻诛仙》的后台管理系统。这个系统由开发者manpy7更新并提供了更多的功能,适用于对游戏进行管理和维护...

    HYXD诛仙易语言源码

    距离计算是源码中的第二个实用功能。在任何游戏中,计算两个对象之间的距离对于实现自动化操作至关重要。例如,自动寻路功能需要计算玩家角色与目的地之间的距离,而自动战斗则依赖于角色与敌人的距离判断。源码提供...

    PHP版梦诛后台_当宝的梦幻诛仙全功能GM后台_

    1. `gsxdb.jar.filepart`:这可能是一个部分下载的Java ARchive (JAR) 文件,通常包含Java类文件和其他资源,可能是用于数据库连接或游戏逻辑的辅助工具。 2. `bg.gif`:背景图像文件,用于美化GM后台的用户界面。 ...

    JAVA技术帮助文档

    2. **面向对象**:Java是一种面向对象的语言,它支持类、对象、继承、封装和多态等面向对象特性。这使得程序设计更加模块化,易于维护和扩展。 3. **分布式计算**:Java内置了网络通信功能,支持TCP/IP协议,方便...

    诛仙游戏账号管理工具_诛仙游戏账号管理工具_诛仙_

    同时,保持软件及数据库的更新,确保与游戏服务器的兼容性。 《诛仙游戏账号管理工具》的出现,极大地简化了游戏账号的管理过程,使玩家能够更加专注于游戏本身,享受游戏带来的乐趣,而不用担忧账号安全问题。无论...

    诛仙3单机el编辑器

    《诛仙3单机el编辑器》是一款专为《诛仙3》单机版设计的游戏辅助工具,旨在帮助玩家更方便地对游戏内的各种元素进行个性化调整。通过这款编辑器,用户可以对游戏中的NPC(非玩家角色)、物品以及出售列表进行编辑,...

    诛仙架设教程.rar

    2. **数据库设置**:《诛仙》的游戏数据存储在数据库中,你需要创建数据库,导入游戏的初始数据,设置用户权限,并确保数据库服务正常运行。 3. **服务端程序安装**:获取《诛仙》的服务端程序,这可能需要从官方...

    易语言诛仙多区多开登陆器源码

    请将多开器复制到诛仙安装目录下的element文夹里运行,本多开器支持不同区服的多开,本版本仅支持四开.游戏,开启后多开器可以关闭,无限多开版本为内部定制版本。资源作者:。@易语言源码大全。资源界面:。资源下载...

    c#编的诛仙技能天赋模拟器

    总的来说,这款由C#编写的《诛仙》技能天赋模拟器,不仅为玩家提供了便利的游戏辅助工具,还促进了玩家之间的交流与学习。它以实际游戏数据为基础,结合C#的强大计算能力,使得玩家在游戏之外也能享受到策略规划的...

    梦幻诛仙物品id大全

    梦幻诛仙物品id大全,一键端使用对照物品id,可添加到商城或者后台发送列表。 丹青11职业版本 比较全的列表。

    墨鱼诛仙源码

    易语言写完美游戏诛仙辅助,方便学习参考!

    诛仙源码

    诛仙源码

    Discuz! 诛仙风格

    2. **论坛风格/模板**:论坛模板决定了论坛的外观和布局,用户可以根据自己的需求和喜好选择或定制模板,改变论坛的视觉效果。 3. **网页模版的结构**:一般包括HTML(页面结构)、CSS(样式控制)、JavaScript...

Global site tag (gtag.js) - Google Analytics