Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AerVexUI

基于 VexView 的高度自定义 UI 配置化插件。通过配置文件定义 GUI 界面、组件布局和交互事件,无需写Jvav即可创建复杂的UI

依赖

  • Bukkit/Spigot 1.8 ~ 1.12
  • VexView >=2.6.10
  • PlaceholderAPI (可选)

获取插件

前往 Actions 页面,点击最近一次构建,在底部 Artifacts 区域下载 AerVexUI 压缩包,解压后即可得到 JAR 文件。

安装

  1. VexView.jar 放入服务端 plugins/ 目录
  2. AerVexUI-1.0.0.jar 放入服务端 plugins/ 目录
  3. 启动服务端,生成 plugins/AerVexUI/ 目录
  4. plugins/AerVexUI/ui/ 下创建你的 UI 配置文件

命令

命令 说明 权限
/aervexui open <ui> [player] 打开指定UI. 当player参数为空时为执行者打开. 控制台必须指定player aervexui.admin
/aervexui reload 重载配置文件 aervexui.admin
/aervexui list 列出所有已加载的UI aervexui.admin

UI配置

配置文件在 plugins/AerVexUI/ui/ 下,以文件名作为UI名

基本结构

no-pointer: false # true->不呼出鼠标, false=普通交互GUI. true了可以当成hud用
render-time: 114514 # nopointer下 UI的显示时长, 单位tick. 不写默认永久
origin: left-top # 坐标系原点

window:
  title: '<背景贴图URL>'
  x: 0
  y: 0
  width: 200
  height: 150
  closable: true

groups:
  <分组id>:
    <组件id>:
      x: '...'
      y: '...'
      width: '...'
      height: '...'
      type: '...'
      # ... 其他属性
      event:
        onClick:
          - '...'

events:
  <事件id>:
    onClick:
      - '...'

window 字段

字段 类型 说明
title String GUI 背景贴图url
x String GUI 显示 X 坐标
y String GUI 显示 Y 坐标
width String GUI 宽度
height String GUI 高度
closable boolean 是否允许玩家通过 Esc/E 键关闭. 默认 true

顶层字段

字段 类型 默认值 说明
no-pointer boolean false 不呼出鼠标指针. true 时玩家可正常操作游戏, UI上的button类型组件可以通过打开聊天栏时用鼠标点击
render-time int 2147483647 组件显示时长(tick, 1秒=20tick). 仅 no-pointer: true 时生效
origin String left-top 坐标原点,决定 x/y 的参考位置

HUD 模式(no-pointer)下 input 类型组件不支持, 会被跳过. 按钮点击依赖 VexView 的 ButtonClickEvent

坐标原点 (origin)

原点值 说明
left-top 左上角(默认). x 向右, y 向下
left-bottom 左下角. x 向右, y 向上
left-center 左侧居中. x 向右, y 从中心上下偏移
right-top 右上角. x 从右向左, y 向下
right-bottom 右下角. x 从右向左, y 向上
right-center 右侧居中. x 从右向左, y 从中心上下偏移
center-top 正上方居中. x 从中心左右偏移, y 向下
center-bottom 正下方居中. x 从中心左右偏移, y 向上
center-center 正中心

原点同时影响 window 位置和组件坐标

单位

x y width height 支持以下单位

单位 示例 说明
px 100100px 像素(默认)
% 50% 相对于父容器(GUI = window, HUD = 屏幕)
vw 50vw 相对于屏幕宽度
vh 50vh 相对于屏幕高度

用法实际上就跟html是一样的

不带单位时默认为px. 单位可以和表达式混合使用 比如 '(50 + 10)%

组件通用字段

所有组件都支持以下字段:

字段 类型 说明
x String X 坐标
y String Y 坐标
width String 宽度
height String 高度
type String 组件类型 imagebuttontextinput
event Object 事件定义 (内联或引用)

组件类型

image - 图片组件

logo:
  x: '10'
  y: '10'
  width: '50'
  height: '50'
  assets: '[local]logo.png'
  type: 'image'
字段 说明
assets 组件素材

button - 按钮组件

confirm_btn:
  x: '60'
  y: '100'
  width: '80'
  height: '20'
  assets: '[local]btn_normal.png'
  assets2: '[local]btn_hover.png'
  type: 'button'
  text: '确认'
  name: 'confirm'
  event:
    onClick:
      - '-msg 你点击了按钮'
字段 说明
assets 按钮默认状态贴图url
assets2 按钮悬停状态贴图url
text 按钮显示文本
name 按钮内部名称

text - 文本组件

title_text:
  x: '10'
  y: '10'
  width: '180'
  height: '20'
  type: 'text'
  text:
    - '§6§l标题'
    - '&7副标题内容'
  scale: 1.2
字段 说明
text 文本内容列表,每项为一行
scale 文本缩放比例,默认 1.0

input - 输入框组件

search_box:
  x: '20'
  y: '50'
  width: '160'
  height: '20'
  type: 'input'
  maxString: 50
  id: 0
  text: '默认文本'
字段 说明
maxString 最大输入字数,默认 50
id 输入框 ID,同一 GUI 内不可重复
text 预置文本内容

表达式

xywidthheight 字段支持数学表达式,可以引用其他组件的属性.

  • VexView坐标系:X轴向右增大,Y轴向下增大,原点为 GUI 左上角
  • 表达式求值仅支持整数运算

引用语法

分组id.组件id.属性

支持的属性:xywidth(或 w)、height(或 h)

示例

groups:
  main:
    header:
      x: '10'
      y: '10'
      width: '180'
      height: '20'
      type: 'text'
      text: ['标题']

    content:
      x: '10'
      y: '(main.header.y + main.header.height + 10)'
      width: '180'
      height: '100'
      type: 'text'
      text: ['内容区域']

    footer:
      x: '(main.content.x + main.content.width - 80)'
      y: '(main.content.y + main.content.height + 5)'
      width: '80'
      height: '20'
      type: 'button'
      assets: '[local]btn.png'
      text: '确定'

支持的运算符:+-*/,支持括号 () 控制优先级

表达式在 UI 打开时一次性求值,结果为整数


占位符

以下占位符可在 textassets、命令等所有文本字段中使用:

占位符 说明
%player_name% 玩家名称
%player_displayname% 玩家显示名
%player_health% 玩家当前血量(int)
%player_level% 玩家经验等级
%player_x% 玩家 X 坐标(int)
%player_y% 玩家 Y 坐标(int)
%player_z% 玩家 Z 坐标(int)
%player_world% 玩家所在世界名

如果 PlaceholderAPI 存在,支持使用占位符


事件系统

事件类型

事件 触发时机 支持组件
onClick 鼠标点击组件 button
onType 任意非移动键按下 所有(通过 GUI 内组件监听)
onType_<key> 指定按键按下 所有
onClose GUI 关闭时 所有
onOver 鼠标悬停(仅 HoverText 显示) 所有(通过 VexHoverText)

按键映射(onType支持的key)

escape1-0backspacetabenterlshiftrshiftlaltspacef1-f12updownleftright

注意:VexView 不监听 WASD 移动键,因此 onType_wonType_aonType_sonType_d 无法使用

事件定义方式

方式一:内联定义

my_button:
  # ...
  event:
    onClick:
      - '-msg 你好'

方式二:引用 events 节

my_button:
  # ...
  event: 'events.my_event'

events:
  my_event:
    onClick:
      - '-msg 你好'

方式三:引用其他组件的事件

my_button:
  # ...
  event: 'main.other_button.onClick'

格式:分组id.组件id.事件类型


命令列表

事件中可使用的命令按顺序由上到下执行

-set 设置组件属性

- '-set -g 分组id -r 组件id --url "<新URL>" --x "10" --y "20"'

-r 参数不允许为空. 支持的 -- 参数:--url--url2--name--x--y--width--height

-create 创建组件

- '-create -g 分组id -r 组件id --type "button" --assets "[local]btn.png" --x "10" --y "20" --width "80" --height "20" --text "按钮" --event "events.my_event"'

如果要创建的组件已存在,等同于先执行 -delete -g 分组id -r 组件id forever 再创建

通过 -create 创建的组件不在原始配置中,因此无法直接定义 event. 可通过以下方式指定:

  • --event eventId:引用 events 节中定义的事件
  • --event 分组id.组件id.eventType:复用其他组件的事件

组件ID(reactId)在同一 GUI 内应唯一. 如果 -create 创建了与已有组件相同分组和 ID 的组件,会先删除旧组件再创建新组件

由于 OpenedVexGui.addDynamicComponent() 限制动态添加的组件如果assets非[local]来源,图片不会显示. 因此 -create-vis true 操作的组件assets应使用 [local]

-delete 删除组件

- '-delete -g 分组id -r 组件id temp'
- '-delete -g 分组id -r 组件id forever'
  • temp:临时删除,下次打开 UI 时会根据配置文件重新表现
  • forever:永久删除,直到插件重载才会重新表现

我用最直白最不绕弯子最..的话向你解释:forever 删除的组件在 /aervexui reload 后会恢复,temp 删除的组件在重新打开 GUI 时恢复

-refresh 刷新组件

- '-refresh -g 分组id -r 组件id'

一般用于 assets URL 内容变更后刷新显示. 执行时会移除再重新添加组件

-vis 设置组件可见性

- '-vis -g 分组id -r 组件id true'
- '-vis -g 分组id -r 组件id false'
- '-vis -g 分组id -r 组件id show'
- '-vis -g 分组id -r 组件id hidden'

true = show = 显示,false = hidden = 隐藏

由于 OpenedVexGui.addDynamicComponent() 限制动态添加的组件如果assets非[local]来源,图片不会显示. 因此 -create-vis true 操作的组件assets应使用 [local]

-console 控制台执行命令

- '-console say 服务器公告'
- '-console give %player_name% diamond 1'

以控制台身份执行命令

-cmd 玩家执行命令

- '-cmd default spawn'
- '-cmd op gamemode creative %player_name%'
  • default:以玩家当前权限执行
  • op:临时提升为op权限执行,执行后恢复原权限

-msg 发送消息

- '-msg &a操作成功!'
- '-msg 你好,%player_name%'

向触发事件的玩家发送消息


条件判断

--if 条件

- '--if player.hasPermission("aervexui.use")'
- '-msg 你有权限'

--if 后面的内容为Jvav表达式,通过Nashorn执行. 可用变量:

变量 类型 说明
player Player 触发事件的玩家对象
Bukkit Bukkit Bukkit 静态工具类
plugin AerVexUI 插件实例

示例:

- '--if player.getLevel() >= 10'
- '--if player.isOp()'
- '--if player.getHealth() > 5'
- '--if player.hasPermission("vip.rank3")'

--else 否则

- '--if player.isOp()'
- '-msg 你是管理员'
- '--else'
- '-msg 你不是管理员'

相当于

if (player.isOp()) {
    player.sendMessage("你是管理员");
} else {
    player.sendMessage("你不是管理员");
}

--exitif 结束条件块

- '--if player.isOp()'
- '-msg 管理员消息'
- '--exitif'
- '-msg 这条消息不受 if 影响'

相当于

if (player.isOp()) {
    player.sendMessage("管理员消息");
}
player.sendMessage("这套消息不受 if 影响");

--exitif 终止最近的 --if 块. 如果不加 --exitif,后续所有命令都在该 --if 内部执行

嵌套条件

条件支持嵌套,通过栈管理:

- '--if player.isOp()'
- '--if player.getLevel() >= 50'
- '-msg 高级管理员'
- '--else'
- '-msg 普通管理员'
- '--exitif'
- '--exitif'
- '-msg 不受任何条件影响'

相当于

if (player.isOp()) {
    if (player.getLevel() >= 50) {
        player.sendMessage("高级管理员");
    } else {
        player.sendMessage("普通管理员");
    }
}
player.sendMessage("不受任何条件影响")

完整配置示例

window:
  title: '[local]menu_bg.png'
  x: -1
  y: -1
  width: 250
  height: 200
  closable: true

groups:
  header:
    title:
      x: '25'
      y: '10'
      width: '200'
      height: '20'
      type: 'text'
      text:
        - '§6§l服务器菜单'
      scale: 1.5

    player_info:
      x: '25'
      y: '(header.title.y + 30)'
      width: '200'
      height: '30'
      type: 'text'
      text:
        - '§7玩家: §f%player_name%'
        - '§7等级: §f%player_level%  §7血量: §c%player_health%'

  buttons:
    warp_btn:
      x: '25'
      y: '(header.player_info.y + 40)'
      width: '90'
      height: '25'
      assets: '[local]btn_normal.png'
      assets2: '[local]btn_hover.png'
      type: 'button'
      text: '传送大厅'
      event:
        onClick:
          - '-cmd default spawn'
          - '-msg &a已传送到大厅'

    shop_btn:
      x: '(buttons.warp_btn.x + buttons.warp_btn.width + 15)'
      y: '(buttons.warp_btn.y)'
      width: '90'
      height: '25'
      assets: '[local]btn_normal.png'
      assets2: '[local]btn_hover.png'
      type: 'button'
      text: '商店'
      event:
        onClick:
          - '-cmd default shop'

    admin_btn:
      x: '25'
      y: '(buttons.warp_btn.y + buttons.warp_btn.height + 10)'
      width: '200'
      height: '25'
      assets: '[local]btn_admin.png'
      assets2: '[local]btn_admin_hover.png'
      type: 'button'
      text: '管理面板'
      event:
        onClick:
          - '--if player.isOp()'
          - '-create -g admin -r panel --type "text" --x "25" --y "140" --width "200" --height "30" --text "§c管理面板已打开"'
          - '--else'
          - '-msg §c需要管理员权限'
          - '--exitif'

  footer:
    close_btn:
      x: '(250 - 90 - 15)'
      y: '(200 - 25 - 10)'
      width: '90'
      height: '25'
      assets: '[local]btn_close.png'
      assets2: '[local]btn_close_hover.png'
      type: 'button'
      text: '关闭'
      event:
        onClick:
          - '-vis -g buttons -r admin_btn hidden'

events:
  admin_panel_event:
    onClick:
      - '-console say %player_name% 打开了管理面板'

License: GPL-3.0 | QQ/VX: AerMini | Mail: aermini@163.com

About

VexView附属 | 高度自定义你的UI!

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages