本帖最后由 1582952890 于 2017-9-17 11:31 编辑
本插件及介绍严禁任何人转载到任何地方
发现标题能写的地方实在太小了,只好在帖内补全这插件的功能了
- 想在你的网站上显示在线人数提高逼格?这个插件帮你做到!
- 想在网站上实现封禁查询,帐号管理,查看统计甚至卫星地图?这个插件帮你做到!
- 想把服务器公告同步到网站或在网站设置服务器公告?这个插件帮你做到!
- 想在网站上管理服务器?这个插件帮你做到!
- 还有啥脑洞想在网站上做的?这个插件帮你做到!没啥不能显示的!任意与服务器交换数据!
- 想开网站但再租服务器很贵不划算?这个插件帮你做到!(只限静态,不推荐做访问量高的大型网站
- 想在除了网页之类的地方(例如php)与服务器交换信息?这个插件帮你做到!
牛逼不?是不是看了以后热血沸腾呐
那我再泼盆凉水
淬火一下
这个插件顾名思义,只是一个接口。这个接口通过Netty框架,让其他插件可通过HTTP / WebSocket / AJAX(也算http)协议来跟服务器交换数据。所以实际跟Vault和ProtocolLib一样只是个壳子,具体实现得自己编写插件或找人定制。
但是我清楚这种纯API类型的插件没个demo你们不会来的,所以我写了个demo(见下
DEMO的演示图片
更改UI之前:
本来想这样算了的,后来强迫症发作想把文本框改为MaterialDesign的,后来整个都改为MaterialDesign了。。
所以要明确一点:这个演示网页的style.css里MaterialDesign风格的相关样式,严禁任何人或组织未经本人明示许可,使用在任何网站上
顺便show了一波网页技术
在没有Netty框架的服务器使用的说明(重要(必看!
1.8以下的服务器的Netty框架(MC与MC服务器所使用的高性能异步IO框架)并不在 io.netty 包而是在 net.minecraft.util.io.netty 包,所以插件启动时会提示找不到 io.netty 的类,而我又不想针对不同的位置写两个版本。
在这种情况下请安装我自己把netty包装为的一个插件 NettyIO。
这个插件其实就是netty加了个 plugin.yml 和空的主类使其能被Bukkit加载,没有任何功能。
NettyIO下载地址: http://pan.baidu.com/s/1slMPRL7
如何判断你的服务器需不需要 NettyIO 这个前置?
使用WinRAR,好压等压缩文件管理器打开服务器的核心,看看里面有没有 io 这个文件夹
如果有这个文件夹,则不需要NettyIO这个前置。如果没有,则需要从上面的链接下载并与插件本体一起放置到 plugins 文件夹。 |
配置文件说明- network:
- ip: "*"
- port: 10240
- accessControlAllowOrigin: ~
复制代码ip 为HTTP/WebSocket服务器进行监听的IP。填localhost则为只有本地可以访问,外网一律不能访问。默认的 * 表示对所有ip开放。这个跟 server.properties 里的 server-ip 选项功能一样的。
port 表示监听的端口,注意端口不能被占用(当然不能填写服务器的端口)
accessControlAllowOrigin 指的是 HTTP 响应头的 Access-Control-Allow-Origin 字段。这个字段控制了Ajax能否跨域访问。
如果你的网站不需要Ajax,或者你根本不知道Ajax是什么,则
不要修改。
如果你打算修改,请务必先阅读以下
默认值 ~ 或 null 代表,其他域(同协议同域名同端口 则判断为同一个域)的Ajax操作不能访问到这个服务器的内容。
例如,你把服务器挂到了 A.com ,然后你的网站在 B.com,需要Ajax请求A.com的数据,那么你就得把这个选项设为 B.com 使B.com能使用Ajax跨域请求。详细内容请百度 Access-Control-Allow-Origin
如果填写 * 则代表任何域名都可以使用Ajax访问你的网站。在以下情况下你可以这样做:任意域名可访问的概念是,攻击者在自己网站上挂段脚本不断的Ajax请求你的服务器就可以轻松达到压测目的并且所有访问者在访问的时间段里都会成为肉鸡。新压测方法Get√ |
演示Demo
WhatTheDemo.jar
(17.9 KB, 下载次数: 212)
Demo用法:
配置文件- onlinelist: # 获得在线人数的模块
- enable: true # 是否开启
- maxPlayerSampleCount: 30 # 在线人数列表sample的最大个数
- playerinfo: # 获得玩家具体信息的模块
- enable: true # 是否开启
- lengthLimit: 350 # WebSocket每次请求的字符串长度限制。字符串的格式是 player1,player2,etc
- playerLimitPerRequest: 50 # Http请求的每次请求个数限制
- webserver: # 网络服务器模块
- enable: true # 是否开启
- rootfolder: wwwroot # 网站根目录。默认位于 plugins/WhatTheDemo/wwwroot/
复制代码
如果网站根目录不存在,将会生成一个自带的网页,效果图见帖子开头
onlinelist使用方法:
http://网站地址/onlinelist?sample=1
会返回一个JSON- {online: 0, max: 20, sample:["player1", "player2"]}
复制代码 online为在线人数,max为最大人数,sample只有当加入了sample=1参数后才会附加进去。
由于 maxPlayerSampleCount 限制,这个sample列表的长度可能小于online
也可以websocket调用,具体方法见我的DEMO网站
playerinfo使用方法:
懒得讲了,去看DEMO网站吧。。。
webserver使用方法:
直接访问 http://网站地址/webserver 即可 |
注意此演示程序的所有功能仅用于演示!没有加严谨的确保安全/限制请求频率等的模块,
请勿放在实际开服环境使用否则后果自负!
开源
本体:
https://github.com/zhouhaha/WebInterface
DEMO:
https://github.com/zhouhaha/What-The-Demo
本体采用
LGPL v3 开源协议发布
DEMO采用
GPL v3 开源协议发布
没事star一个呗
MCSTATS
↑加载可能需要时间
嗯。。让我想想还有什么要讲的
对了,API
开发者专题
本来想让你们直接去看DEMO的。。为了避免被打死我还是讲一下吧。。自不必说
注意:为了导入到Netty的包,IDE的库不能使用API而必须使用
1、1.8或1.8以上的服务端核心
或者...
2、任意版本的服务端核心 与 NettyIO 插件(上面提供
在onEnable里添加- API.registerModule("moduleName", module);
复制代码 例如如果moduleName为"webserver",那么就可以通过 http://网站地址/webserver 来访问这个模块
moduleName 没有限制,但是请取名为 英文数字下划线。如果使用中文,或"/"或"",虽然不会报错,但会导致这个模块永远无法调用,除非用监听器更改模块id(见下。
module必须为 HttpModule接口 或 WebSocketModule接口 的实例。直接实现 Module接口 是没用的!
如果module同时为 HttpModule 与 WebSocketModule 的实例,那么就会一起注册为 Http模块 与 WebSocket模块,不需要注册两次。
然后就是模块怎么实现了。先讲HTTP的- public abstract interface HttpModule extends Module{
- public FullHttpResponse handleRequest(String uri, HttpParams param, FullHttpRequest request);
- }
复制代码 handleRequest 表示一个HTTP请求。
URI的意义为: http://address/moduleName/uri/uri/uri?params1=value1?ms2=value2
加粗的部分则为传入的URI。注意如果moduleName后没有"/",系统也会自动添加一个。
HttpParams 表示请求附加的参数。这个里面包含了POST与GET的参数,考虑到了RequestMethod是POST但是RequestURI里面也有参数的情况。
FullHttpRequest 就是底层的请求了。会Netty可以用它获得更多例如headers的信息。
返回值是一个Netty的FullHttpResponse。两种选择。
1、会Netty- FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
- // ....
- return response;
复制代码 2、不会Netty或想使用简便方法。- return Utils.INSTANCE.builder()
- .content("Hello world")
- .contentType(MIME_TEXT, true)
- .header("CustomHeader", "abcdef")
- .build();
复制代码 想返回一个错误- return Utils.INSTANCE.sendError(HttpResponseStatus.NOT_FOUND, "您要找的页面被小黑搬走了");
复制代码 够简单了吧?还有更多简便方法请查 Utils 类中的方法。
接下来是WebSocket模块- public abstract interface WebSocketModule extends Module{
- public WebSocketConnection newConnect(ChannelHandlerContext context,
- WebSocketServerHandshaker handshaker,
- String uri,
- HttpParams param,
- FullHttpRequest request);
- }
复制代码 示例- @Override
- public WebSocketConnection newConnect(ChannelHandlerContext context,
- WebSocketServerHandshaker handshaker, String uri,
- HttpParams param, FullHttpRequest request) {
- return new WebSocketConnection(handshaker, context) {
- @Override
- public void register() throws Exception{
- System.out.println("新连接");
- }
- @Override
- public void handleDisconnect() throws Exception{
- System.out.println("连接已断开");
- }
-
- @Override
- public void handleTextMessage(ChannelHandlerContext context,
- String msg) throws Exception {
- sendText("echo: "+msg);
- System.out.println("收到消息 "+msg);
- }
-
- @Override
- public void handleBinaryMessage(ChannelHandlerContext context,
- ByteBufHolder data) throws Exception {
- throw new Exception("收到一条二进制消息, 这个DEMO不支持"); // 抛出的异常会转移到 handleException 处理
- }
- @Override
- public void handleException(ChannelHandlerContext context,
- Throwable ex) {
- System.out.println("发生错误: "+ex.toString());
- context.close(); // 断开连接
- }
- };
- }
复制代码 也很简单。参数 uri , param,request 解释过了(由于WebSocket建立连接也是通过HTTP协议,所以这3个是相同的)。
context 和 handshaker 不会Netty可以不用管,WebSocketConnection 类会自动处理。
所有方法的意思相信已经写的很明白了。所有方法的重写都是可选的。
WebSocketConnection还自带了一个 sendBinary方法用于发送二进制消息。
事件 ModuleRequestEvent 在收到一个请求(不管是Http请求还是WebSocket连接请求)时触发。
可以通过它来修改模块ID。例如理论上应该可以 判断模块ID为"",就重定向到一个模块,这样就可以实现利用根目录。不过我没试过。。
这个事件如果被取消,用户会收到一条错误信息- Utils.INSTANCE.sendError(FORBIDDEN, "The request has been canceled by an event listener", ctx);
复制代码 如果对方的代码(记住这个是网页接口,显示的数据是给机器看的)处理的不好可能会出错,因此不建议随便取消这个事件。 |
下载
http://pan.baidu.com/s/1i5fgNtV
可选前置NettyIO(是否需要请看上面)下载
http://pan.baidu.com/s/1slMPRL7
记得评分
如果你的插件报了这个错误Caused by: java.lang.ClassNotFoundException: io.netty.channel.EventLoopGroup
at java.net.URLClassLoader.findClass(Unknown Source) ~[?:1.8.0_92]
请安装前置 NettyIO!!!