From 26547a0c465d861fb684a6504b28231217c27eaa Mon Sep 17 00:00:00 2001 From: F0rb1d Date: Wed, 8 Aug 2018 19:41:31 +0800 Subject: [PATCH 01/18] Updated Simplified Chinese language. --- Plan/src/main/resources/locale/locale_CN.txt | 519 ++++++++++--------- 1 file changed, 260 insertions(+), 259 deletions(-) diff --git a/Plan/src/main/resources/locale/locale_CN.txt b/Plan/src/main/resources/locale/locale_CN.txt index 332781af1..d7c7c33eb 100644 --- a/Plan/src/main/resources/locale/locale_CN.txt +++ b/Plan/src/main/resources/locale/locale_CN.txt @@ -1,314 +1,315 @@ Cmd - Click Me || 点击此处 Cmd - Link || §7 •§2 链接:§f -Cmd Disable - Disabled || §aPlan systems are now disabled. You can still use /planbungee reload to restart the plugin. +Cmd Disable - Disabled || §a现已禁用计划系统。阁下仍可使用 /planbungee reload 重启插件。 Cmd FAIL - Invalid Username || §c[计划] 此玩家不存在。 -Cmd FAIL - No Feature || §eDefine a feature to disable! (currently supports ${0}) +Cmd FAIL - No Feature || §e请定义要禁用的功能!(当前支持 ${0}) Cmd FAIL - No Permission || §c[计划] 阁下没有所需权限。 Cmd FAIL - Require only one Argument || §c[计划] 命令需要一个参数。 Cmd FAIL - Requires Arguments || §c[计划] 命令缺少参数。${0} Cmd FAIL - Unknown Username || §c[计划] 未在数据库中找到此玩家。 -Cmd FAIL - WebUser does not exists || §cUser does not exists! -Cmd FAIL - WebUser exists || §cUser already exists! +Cmd FAIL - WebUser does not exists || §c用户不存在! +Cmd FAIL - WebUser exists || §c用户已存在! Cmd Header - Analysis || §f»§2 玩家统计 - 统计结果 Cmd Header - Info || §f»§2 玩家统计 - 信息 Cmd Header - Inspect || §f»§2 玩家统计 - 检视结果: -Cmd Header - Network || > §2Network Page -Cmd Header - Players || > §2Players +Cmd Header - Network || > §2网络页面 +Cmd Header - Players || > §2玩家 Cmd Header - Search || §f»§2 玩家统计 - 搜索结果: -Cmd Header - Servers || > §2Servers -Cmd Header - Web Users || > §2${0} Web Users -Cmd Info - Bungee Connection || §2Connected to Bungee: §f${0} -Cmd Info - Database || §2Active Database: §f${0} -Cmd Info - Reload Complete || §aReload Complete -Cmd Info - Reload Failed || §cSomething went wrong during reload of the plugin, a restart is recommended. -Cmd Info - Update || §2Update Available: §f${0} -Cmd Info - Version || §2Version: §f${0} -Cmd Notify - No WebUser || You might not have a web user, use /plan register -Cmd Notify - WebUser register || Registered new user: '${0}' Perm level: ${1} -Cmd Qinspect - Activity Index || §2Activity Index: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Deaths: §f${0} -Cmd Qinspect - Geolocation || §2Logged in from: §f${0} -Cmd Qinspect - Last Seen || §2Last Seen: §f${0} -Cmd Qinspect - Longest Session || §2Longest Session: §f${0} -Cmd Qinspect - Mob Kills || §2Mob Kills: §f${0} -Cmd Qinspect - Player Kills || §2Player Kills: §f${0} -Cmd Qinspect - Playtime || §2Playtime: §f${0} -Cmd Qinspect - Registered || §2Registered: §f${0} -Cmd Qinspect - Times Kicked || §2Times Kicked: §f${0} -Cmd Setup - Allowed || §aSet-up is now Allowed -Cmd Setup - Bad Request || §eConnection succeeded, but Receiving server was not a Bungee server. Use Bungee address instead. -Cmd Setup - Disallowed || §cSet-up is now Forbidden -Cmd Setup - Forbidden || §eConnection succeeded, but Bungee has set-up mode disabled - use '/planbungee setup' to enable it. -Cmd Setup - Gateway Error || §eConnection succeeded, but Bungee failed to connect to this server (Did current web server restart?). Use /plan m con & /planbungee con to debug. -Cmd Setup - Generic Fail || §eConnection failed: ${0} -Cmd Setup - Internal Error || §eConnection succeeded. ${0}, check possible ErrorLog on receiving server's debug page. -Cmd Setup - Success || §aConnection successful, Plan may restart in a few seconds.. -Cmd Setup - Unauthorized || §eConnection succeeded, but Receiving server didn't authorize this server. Contact Discord for support -Cmd Setup - Url mistake || §cMake sure you're using the full address (Starts with http:// or https://) - Check Bungee enable log for the full address. -Cmd Setup - WebServer not Enabled || §cWebServer is not enabled on this server! Make sure it enables on boot! -Cmd SUCCESS - Feature disabled || §aDisabled '${0}' temporarily until next plugin reload. -Cmd SUCCESS - WebUser register || §aAdded a new user (${0}) successfully! -Cmd Update - Cancel Success || §aCancel operation performed. -Cmd Update - Cancelled || §cUpdate cancelled. -Cmd Update - Change log || Change Log v${0}: -Cmd Update - Fail Cacnel || §cUpdate failed on a server, cancelling update on all servers.. -Cmd Update - Fail Force Notify || §e${0} failed to update, -force specified, continuing update. -Cmd Update - Fail Not Online || §cNot all servers were online or accessible, you can still update available servers using /plan update -u -force -Cmd Update - Notify Cancel || §aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel. -Cmd Update - Online Check || Checking that all servers are online.. -Cmd Update - Scheduled || §a${0} scheduled for update. -Cmd Update - Url mismatch || §cVersion download url did not start with ${0} and might not be trusted. You can download this version manually here (Direct download): -Cmd Web - Permission Levels || >\§70: Access all pages\§71: Access '/players' and all player pages\§72: Access player page with the same username as the webuser\§73+: No permissions +Cmd Header - Servers || > §2服务器 +Cmd Header - Web Users || > §2${0} 个网页用户 +Cmd Info - Bungee Connection || §2已连接至 Bungee:§f${0} +Cmd Info - Database || §2活跃数据库:§f${0} +Cmd Info - Reload Complete || §a重新载入完毕 +Cmd Info - Reload Failed || §c重载插件时发生错误,建议重新启动服务器。 +Cmd Info - Update || §2更新可用:§f${0} +Cmd Info - Version || §2版本:§f${0} +Cmd Notify - No WebUser || 阁下可能还没有网页账户,请输入 /plan register <密码> +Cmd Notify - WebUser register || 已注册新用户:'${0}' 权限级别:${1} +Cmd Qinspect - Activity Index || §2活动索引:§f${0} | ${1} +Cmd Qinspect - Deaths || §2死亡数:§f${0} +Cmd Qinspect - Geolocation || §2从 §f${0} 处登录 +Cmd Qinspect - Last Seen || §2最后在线:§f${0} +Cmd Qinspect - Longest Session || §2最长在线时间:§f${0} +Cmd Qinspect - Mob Kills || §2怪物击杀数:§f${0} +Cmd Qinspect - Player Kills || §2玩家击杀数:§f${0} +Cmd Qinspect - Playtime || §2游玩时间:§f${0} +Cmd Qinspect - Registered || §2注册时间:§f${0} +Cmd Qinspect - Times Kicked || §2踢出次数:§f${0} +Cmd Setup - Allowed || §a现已允许安装 +Cmd Setup - Bad Request || §e连接成功,但接收服务器不是 Bungee 服务器。请使用 Bungee 地址。 +Cmd Setup - Disallowed || §c现已禁止安装 +Cmd Setup - Forbidden || §e连接成功,但 Bungee 已禁用安装模式 - 请使用 '/planbungee setup' 启用。 +Cmd Setup - Gateway Error || §e连接成功,但 Bungee 无法与此服务器建立连接(是否重启了当前网页服务器?)请使用 /plan m con 与 /planbungee con 进行调试。 +Cmd Setup - Generic Fail || §e连接失败:${0} +Cmd Setup - Internal Error || §e连接成功。${0},请检查接收服务器调试页面的错误日志。 +Cmd Setup - Success || §a连接成功,计划可能将在几秒内重启··· +Cmd Setup - Unauthorized || §e连接成功,但接收服务器并未授权此服务器。请在 Discord 上联系以寻求帮助 +Cmd Setup - Url mistake || §c请确保阁下所输入的是完整地址(以 http:// 或 https:// 开头)- 请检查 Bungee 启用日志获取完整地址。 +Cmd Setup - WebServer not Enabled || §c未在此服务器上启用网页服务器!请确保其在开机时启用! +Cmd SUCCESS - Feature disabled || §a已在下次插件重载前暂时禁用 '${0}'。 +Cmd SUCCESS - WebUser register || §a已成功添加新用户(${0})! +Cmd Update - Cancel Success || §a已完成取消操作。 +Cmd Update - Cancelled || §c已取消更新。 +Cmd Update - Change log || 更新日志 版本${0}: +Cmd Update - Fail Cacnel || §c某个服务器更新失败,正在取消所有服务器的更新··· +Cmd Update - Fail Force Notify || §e${0} 无法更新,但使用了 -force,正在继续更新。 +Cmd Update - Fail Not Online || §c并非所有服务器均在线或可访问,阁下仍可通过使用 /plan update -u -force 的方式强制更新。 +Cmd Update - Notify Cancel || §a阁下可以使用 /plan update cancel 以取消尚未重启的服务器上的更新。 +Cmd Update - Online Check || 正在检查是否所有服务器均在线··· +Cmd Update - Scheduled || §a已为 ${0} 计划了更新。 +Cmd Update - Url mismatch || §c版本下载网址不以 ${0} 开头故可能不受信任。阁下可手动下载此版本(直接下载): +Cmd Web - Permission Levels || >\§70:访问所有页面\§71:访问 '/players' 及所有玩家页\§72:访问用户名与网页用户名一致的玩家页\§73+:无权限 Command Help - /plan analyze || 查看服务器分析 -Command Help - /plan dev || Development mode command +Command Help - /plan dev || 开发模式命令 Command Help - /plan help || 查看命令列表。 Command Help - /plan info || 查看计划版本 Command Help - /plan inspect || 检视玩家数据 Command Help - /plan manage || 数据库管理命令 Command Help - /plan manage backup || 备份数据库至 .db 文件 Command Help - /plan manage clear || 从数据库中清空所有数据 -Command Help - /plan manage con || Debug Server-Bungee connections -Command Help - /plan manage disable || Disable a feature temporarily +Command Help - /plan manage con || 调试服务器至 Bungee 的连接 +Command Help - /plan manage disable || 暂时禁用功能 Command Help - /plan manage hotswap || 热插拔数据库并重启插件 Command Help - /plan manage import || 从插件中导入数据 Command Help - /plan manage move || 在数据库间移动数据 Command Help - /plan manage remove || 从活跃数据库中移除玩家数据 Command Help - /plan manage restore || 恢复数据库 -Command Help - /plan manage setup || Set-up Server-Bungee connection -Command Help - /plan network || View the Network Page +Command Help - /plan manage setup || 设置服务器至 Bungee 的连接 +Command Help - /plan network || 查看网络页面 Command Help - /plan players || 列出所有已缓存玩家名单 Command Help - /plan qinspect || 在游戏内检视玩家数据 -Command Help - /plan register || Register a Web User +Command Help - /plan register || 注册网页用户 Command Help - /plan reload || 重新启动插件(重载配置) Command Help - /plan search || 搜索玩家 -Command Help - /plan servers || List servers in Database -Command Help - /plan update || Get change log link or update plugin +Command Help - /plan servers || 列出数据库中的服务器 +Command Help - /plan update || 获取更新日志链接或更新插件 Command Help - /plan web check || 检查网页用户的权限级别。 Command Help - /plan web delete || 删除网页用户 Command Help - /plan web level || 权限级别信息 -Command Help - /plan web list || List Web Users +Command Help - /plan web list || 列出网页用户 Command Help - /plan webuser || 管理网页用户 -Command Help - /planbungee con || Debug Bungee-Server connections -Command Help - /planbungee disable || Disable the plugin temporarily -Command Help - /planbungee setup || Toggle set-up mode -Database - Apply Patch || Applying Patch: ${0}.. -Database - Patches Applied || All database patches applied successfully. -Database - Patches Applied Already || All database patches already applied. -Database MySQL - Launch Options Error || Launch Options were faulty, using default (${0}) -Database Notify - Clean || Removed data of ${0} players. -Database Notify - SQLite No WAL || SQLite WAL mode not supported on this server version, using default. This may or may not affect performance. +Command Help - /planbungee con || 调试 Bungee 至服务器的连接 +Command Help - /planbungee disable || 暂时禁用插件 +Command Help - /planbungee setup || 开关设置功能 +Database - Apply Patch || 正在应用更新:${0}··· +Database - Patches Applied || 已成功应用所有数据库补丁。 +Database - Patches Applied Already || 已应用所有数据库补丁。 +Database MySQL - Launch Options Error || 启动参数出错,正使用默认参数(${0}) +Database Notify - Clean || 移除了 ${0} 位用户的数据。 +Database Notify - SQLite No WAL || 此服务器版本不支持 SQLite WAL 模式,正使用默认模式。这可能会影响性能。 Disable || 已禁用玩家分析。 -Disable - Processing || Processing critical unprocessed tasks. (${0}) -Disable - Processing Complete || Processing complete. +Disable - Processing || 正在处理未处理的关键任务。(${0}) +Disable - Processing Complete || 处理完毕。 Disable - WebServer || 正在关闭网页服务器··· Enable || 已启用玩家分析。 Enable - Database || ${0}-已建立数据库连接。 -Enable - Notify Address Confirmation || Make sure that this address points to THIS Server: ${0} -Enable - Notify Empty IP || IP in server.properties is empty & AlternativeIP is not in use. Incorrect links will be given! -Enable - Notify Geolocations disabled || Geolocation gathering is not active. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan Requires internet access on first run to download GeoLite2 Geolocation database. -Enable - Notify Webserver disabled || WebServer was not initialized. (WebServer.DisableWebServer: true) +Enable - Notify Address Confirmation || 确保此地址指向此服务器:${0} +Enable - Notify Empty IP || server.properties 中的 IP 为空且未使用替代 IP。这将给出错误地址! +Enable - Notify Geolocations disabled || 地理位置收集不活跃。(Data.Geolocations: false) +Enable - Notify Geolocations Internet Required || 计划需要在首次运行时访问互联网以下载 GeoLite2 地理位置数据库。 +Enable - Notify Webserver disabled || 未初始化网页服务器。(WebServer.DisableWebServer: true) Enable - WebServer || 正在初始化网页服务器··· Enable FAIL - Database || ${0}-连接数据库失败:${1} -Enable FAIL - Database Patch || Database Patching failed, plugin has to be disabled. Please report this issue -Enable FAIL - GeoDB Write || Something went wrong saving the downloaded GeoLite2 Geolocation database -Enable FAIL - WebServer (Bungee) || WebServer did not initialize! +Enable FAIL - Database Patch || 数据库补丁失败,插件必须被禁用。请汇报此问题 +Enable FAIL - GeoDB Write || 保存已下载的 GeoLite2 地理位置数据库时发生问题 +Enable FAIL - WebServer (Bungee) || 网页服务器未初始化 Enable FAIL - Wrong Database Type || ${0} 此数据类型不存在。 -HTML - ACTIVITY_INDEX || Activity Index -HTML - ALL || ALL -HTML - ALL_TIME_PEAK || All Time Peak -HTML - AVERAGE_PING || Average Ping -HTML - AVG || AVG -HTML - BANNED || Banned -HTML - BEST_PING || Best Ping -HTML - CALENDAR || CALENDAR -HTML - CALENDAR_TEXT || Calendar -HTML - CHUNKS || Chunks -HTML - COMMAND || Command -HTML - COMMNAND_USAGE || Command Usage -HTML - CONNECTION_INFORMATION || Connection Information -HTML - COUNTRY || Country -HTML - CURRENT_PLAYERBASE || Current Playerbase -HTML - DEATHS || Deaths -HTML - ENTITIES || Entities -HTML - ERROR || Authentication failed due to error -HTML - FAVORITE_SERVER || Favorite Server -HTML - GEOLOCATION || Geolocation -HTML - GEOLOCATION_TEXT || Geolocation -HTML - HEALTH_ESTIMATE || Health Estimate -HTML - INDEX_ACTIVE || Active -HTML - INDEX_INACTIVE || Inactive -HTML - INDEX_IRREGULAR || Irregular -HTML - INDEX_REGULAR || Regular -HTML - INDEX_VERY_ACTIVE || Very Active -HTML - IP_ADDRESS || IP-address -HTML - KILLED || Killed -HTML - KILLED_BY || Killed by -HTML - LAST_24_HOURS || LAST 24 HOURS -HTML - LAST_30_DAYS || LAST 30 DAYS -HTML - LAST_30_DAYS_TEXT || Last 30 Days -HTML - LAST_7_DAYS || LAST 7 DAYS -HTML - LAST_CONNECTED || Last Connected -HTML - LAST_PEAK || Last Peak -HTML - LAST_SEEN || LAST SEEN -HTML - LAST_SEEN_TEXT || Last Seen -HTML - LOADED_CHUNKS || Loaded Chunks -HTML - LOADED_ENTITIES || Loaded Entities -HTML - LOCAL_MACHINE || Local Machine -HTML - LONGEST || Longest -HTML - LOW_TPS_SPIKES || Low TPS Spikes -HTML - MOB_CAUSED_DEATHS || Mob caused Deaths -HTML - MOB_KDR || Mob KDR -HTML - MOB_KILLS || Mob Kills -HTML - MOST_RECENT_SESSIONS || Most Recent Sessions -HTML - NAME || Name -HTML - NAV_COMMAND_USAGE || Command Usage -HTML - NAV_GEOLOCATIONS || Geolocations -HTML - NAV_INFORMATION || Information -HTML - NAV_NETWORK_PLAYERS || Network Players -HTML - NAV_ONLINE_ACTIVITY || Online Activity -HTML - NAV_OVERVIEW || Overview -HTML - NAV_PERFORMANCE || Performance -HTML - NAV_PLAYERS || Players -HTML - NAV_PLUGINS || Plugins -HTML - NAV_SESSIONS || Sessions -HTML - NAV_SEVER_HEALTH || Server Health -HTML - NETWORK || Network -HTML - NETWORK_INFORMATION || NETWORK INFORMATION -HTML - NEW || NEW -HTML - NEW_CALENDAR || New: -HTML - NEW_PLAYERS_TEXT || New Players -HTML - NEW_RETENTION || New Player Retention -HTML - NEW_TEXT || New -HTML - NICKNAME || Nickname -HTML - NO_KILLS || No Kills -HTML - NO_PLAYER_CAUSED_DEATHS || No Player caused Deaths -HTML - OFFLINE || Offline -HTML - ONLINE || Online -HTML - ONLINE_ACTIVITY || ONLINE ACTIVITY -HTML - OPERATOR || Operator -HTML - OVERVIEW || OVERVIEW -HTML - PER_DAY || / Day -HTML - PLAYER_CAUSED_DEATHS || Player caused Deaths -HTML - PLAYER_KILLS || Player Kills -HTML - PLAYER_LIST || Player List -HTML - PLAYERBASE_DEVELOPMENT || Playerbase Development -HTML - PLAYERS || PLAYERS -HTML - PLAYERS_ONLINE || PLAYERS ONLINE -HTML - PLAYERS_ONLINE_TEXT || Players Online -HTML - PLAYERS_TEXT || Players -HTML - PLAYTIME || Playtime -HTML - PLEASE_WAIT || Please wait... -HTML - PREDICETED_RETENTION || Predicted Retention -HTML - PUNCH_CARD || Punchcard -HTML - PUNCHCARD || PUNCHCARD -HTML - RECENT_LOGINS || RECENT LOGINS -HTML - REGISTERED || REGISTERED -HTML - REGISTERED_TEXT || Registered -HTML - REGULAR || REGULAR -HTML - SEEN_NICKNAMES || Seen Nicknames -HTML - SERVER || Server -HTML - SERVER_ANALYSIS || Server Analysis -HTML - SERVER_HEALTH_ESTIMATE || Server Health Estimate -HTML - SERVER_INFORMATION || SERVER INFORMATION -HTML - SERVER_PREFERENCE || Server Preference -HTML - SERVERS || Servers -HTML - SESSION || Session -HTML - SESSION_ENDED || Session Ended -HTML - SESSION_LENGTH || Session Lenght -HTML - SESSION_MEDIAN || Session Median -HTML - SESSIONS || Sessions -HTML - TIME || Time -HTML - TIMES_KICKED || Times Kicked -HTML - TIMES_USED || Times Used -HTML - TOTAL_ACTIVE_TEXT || Total Active -HTML - TOTAL_AFK || Total AFK -HTML - TOTAL_PLAYERS || Total Players -HTML - TOTAL_PLAYTIME || Total Playtime -HTML - UNIQUE || UNIQUE -HTML - UNIQUE_CALENDAR || Unique: -HTML - UNIQUE_PLAYERS || UNIQUE PLAYERS -HTML - UNIQUE_PLAYERS_TEXT || Unique Players -HTML - UNIQUE_TEXT || Unique -HTML - USAGE || Usage -HTML - USED_COMMANDS || Used Commands -HTML - USER_AND_PASS_NOT_SPECIFIED || User and Password not specified -HTML - USER_DOES_NOT_EXIST || User does not exist -HTML - USER_INFORMATION || USER INFORMATION -HTML - USER_PASS_MISMATCH || User and Password did not match -HTML - WITH || With -HTML - WORLD || World -HTML - WORLD_LOAD || WORLD LOAD -HTML - WORLD_PLAYTIME || World Playtime -HTML - WORST_PING || Worst Ping -HTML ERRORS - ACCESS_DENIED_403 || Access Denied -HTML ERRORS - ANALYSIS_REFRESH || Analysis is being refreshed.. -HTML ERRORS - ANALYSIS_REFRESH_LONG || Analysis is being run, refresh the page after a few seconds.. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Ensure you have registered a user with /plan register
- Check that the username and password are correct
- Username and password are case-sensitive

If you have forgotten your password, ask a staff member to delete your old user and re-register. -HTML ERRORS - AUTHENTICATION_FAIlED_401 || Authentication Failed. -HTML ERRORS - FORBIDDEN_403 || Forbidden -HTML ERRORS - NO_SERVERS_404 || No Servers online to perform the request. -HTML ERRORS - NOT_FOUND_404 || Not Found -HTML ERRORS - NOT_PLAYED_404 || Player has not played on this server. -HTML ERRORS - PAGE_NOT_FOUND_404 || Page does not exist. -HTML ERRORS - UNAUTHORIZED_401 || Unauthorized -HTML ERRORS - UNKNOWN_PAGE_404 || Make sure you're accessing a link given by a command, Examples:

/player/PlayerName
/server/ServerName

-HTML ERRORS - UUID_404 || Player UUID was not found in the database. +HTML - ACTIVITY_INDEX || 活动索引 +HTML - ALL || 全部 +HTML - ALL_TIME_PEAK || 所有时间峰值 +HTML - AVERAGE_PING || 平均延迟 +HTML - AVG || 平均 +HTML - BANNED || 已封禁 +HTML - BEST_PING || 最低延迟 +HTML - CALENDAR || 日历 +HTML - CALENDAR_TEXT || 日历 +HTML - CHUNKS || 区块 +HTML - COMMAND || 命令 +HTML - COMMNAND_USAGE || 命令用法 +HTML - CONNECTION_INFORMATION || 连接信息 +HTML - COUNTRY || 国家 +HTML - CURRENT_PLAYERBASE || 当前玩家 +HTML - DEATHS || 死亡数 +HTML - ENTITIES || 实体数 +HTML - ERROR || 认证时发生错误 +HTML - FAVORITE_SERVER || 喜爱的服务器 +HTML - GEOLOCATION || 地理位置 +HTML - GEOLOCATION_TEXT || 地理位置 +HTML - HEALTH_ESTIMATE || 预计健康度 +HTML - INDEX_ACTIVE || 活跃 +HTML - INDEX_INACTIVE || 不活跃 +HTML - INDEX_IRREGULAR || 偶尔 +HTML - INDEX_REGULAR || 经常 +HTML - INDEX_VERY_ACTIVE || 非常活跃 +HTML - IP_ADDRESS || IP 地址 +HTML - KILLED || 被击杀 +HTML - KILLED_BY || 击杀者 +HTML - LAST_24_HOURS || 过去 24 小时 +HTML - LAST_30_DAYS || 过去 30 天 +HTML - LAST_30_DAYS_TEXT || 过去 30 天 +HTML - LAST_7_DAYS || 过去 7 天 +HTML - LAST_CONNECTED || 最后连接 +HTML - LAST_PEAK || 上次峰值 +HTML - LAST_SEEN || 最后在线 +HTML - LAST_SEEN_TEXT || 最后在线 +HTML - LOADED_CHUNKS || 已加载的区块 +HTML - LOADED_ENTITIES || 已加载的实体 +HTML - LOCAL_MACHINE || 本机 +HTML - LONGEST || 最长 +HTML - LOW_TPS_SPIKES || 最低 TPS 值 +HTML - MOB_CAUSED_DEATHS || 被怪物击杀数 +HTML - MOB_KDR || 怪物击杀比 +HTML - MOB_KILLS || 怪物击杀数 +HTML - MOST_RECENT_SESSIONS || 最近会话 +HTML - NAME || 名称 +HTML - NAV_COMMAND_USAGE || 指令用法 +HTML - NAV_GEOLOCATIONS || 地理位置 +HTML - NAV_INFORMATION || 信息 +HTML - NAV_NETWORK_PLAYERS || 网络玩家 +HTML - NAV_ONLINE_ACTIVITY || 在线活动 +HTML - NAV_OVERVIEW || 预览 +HTML - NAV_PERFORMANCE || 性能 +HTML - NAV_PLAYERS || 玩家 +HTML - NAV_PLUGINS || 插件 +HTML - NAV_SESSIONS || 会话 +HTML - NAV_SEVER_HEALTH || 服务器健康度 +HTML - NETWORK || 网络 +HTML - NETWORK_INFORMATION || 网络信息 +HTML - NEW || 新建 +HTML - NEW_CALENDAR || 新: +HTML - NEW_PLAYERS_TEXT || 新玩家 +HTML - NEW_RETENTION || 新玩家保留 +HTML - NEW_TEXT || 新建 +HTML - NICKNAME || 昵称 +HTML - NO_KILLS || 无击杀数 +HTML - NO_PLAYER_CAUSED_DEATHS || 无被玩家击杀数 +HTML - OFFLINE || 离线 +HTML - ONLINE || 在线 +HTML - ONLINE_ACTIVITY || 在线活动 +HTML - OPERATOR || 操作员 +HTML - OVERVIEW || 预览 +HTML - PER_DAY || / 天 +HTML - PLAYER_CAUSED_DEATHS || 被玩家击杀数 +HTML - PLAYER_KILLS || 玩家击杀数 +HTML - PLAYER_LIST || 玩家列表 +HTML - PLAYERBASE_DEVELOPMENT || 玩家发展 +HTML - PLAYERS || 玩家 +HTML - PLAYERS_ONLINE || 在线玩家 +HTML - PLAYERS_ONLINE_TEXT || 在线玩家 +HTML - PLAYERS_TEXT || 玩家 +HTML - PLAYTIME || 游玩时间 +HTML - PLEASE_WAIT || 请稍候··· +HTML - PREDICETED_RETENTION || 预计保留 +HTML - PUNCH_CARD || 打卡签到 +HTML - PUNCHCARD || 打卡签到 +HTML - RECENT_LOGINS || 近期登陆 +HTML - REGISTERED || 已注册 +HTML - REGISTERED_TEXT || 已注册 +HTML - REGULAR || 经常 +HTML - SEEN_NICKNAMES || 可见昵称 +HTML - SERVER || 服务器 +HTML - SERVER_ANALYSIS || 服务器分析 +HTML - SERVER_HEALTH_ESTIMATE || 服务器健康估计 +HTML - SERVER_INFORMATION || 服务器信息 +HTML - SERVER_PREFERENCE || 服务器偏好设置 +HTML - SERVERS || 服务器 +HTML - SESSION || 会话 +HTML - SESSION_ENDED || 会话已结束 +HTML - SESSION_LENGTH || 会话长度 +HTML - SESSION_MEDIAN || 会话中位数 +HTML - SESSIONS || 会话 +# Not sure if this is the time or count of numbers. +HTML - TIME || 次数 +HTML - TIMES_KICKED || 被踢次数 +HTML - TIMES_USED || 使用次数 +HTML - TOTAL_ACTIVE_TEXT || 总活跃玩家 +HTML - TOTAL_AFK || 总挂机玩家 +HTML - TOTAL_PLAYERS || 总玩家 +HTML - TOTAL_PLAYTIME || 总在线时长 +HTML - UNIQUE || 唯一 +HTML - UNIQUE_CALENDAR || 唯一: +HTML - UNIQUE_PLAYERS || 唯一玩家 +HTML - UNIQUE_PLAYERS_TEXT || 唯一玩家 +HTML - UNIQUE_TEXT || 唯一 +HTML - USAGE || 用法 +HTML - USED_COMMANDS || 使用的命令 +HTML - USER_AND_PASS_NOT_SPECIFIED || 未指定用户名与密码 +HTML - USER_DOES_NOT_EXIST || 用户不存在 +HTML - USER_INFORMATION || 用户信息 +HTML - USER_PASS_MISMATCH || 用户名与密码不匹配 +HTML - WITH || 与 +HTML - WORLD || 世界 +HTML - WORLD_LOAD || 世界载入 +HTML - WORLD_PLAYTIME || 世界游玩时间 +HTML - WORST_PING || 最高延迟 +HTML ERRORS - ACCESS_DENIED_403 || 拒绝访问 +HTML ERRORS - ANALYSIS_REFRESH || 正在刷新分析··· +HTML ERRORS - ANALYSIS_REFRESH_LONG || 正在执行分析,请在几秒后刷新页面··· +HTML ERRORS - AUTH_FAIL_TIPS_401 || - 确保阁下已使用 /plan register 注册用户
- 检查用户名与密码是否正确
- 用户名与密码区分大小写

若阁下忘记了密码,请让工作人员删除阁下的旧密码并重新注册。 +HTML ERRORS - AUTHENTICATION_FAIlED_401 || 认证失败。 +HTML ERRORS - FORBIDDEN_403 || 禁止访问 +HTML ERRORS - NO_SERVERS_404 || 无可执行此请求的在线服务器。 +HTML ERRORS - NOT_FOUND_404 || 未找到 +HTML ERRORS - NOT_PLAYED_404 || 玩家从未在此服务器上游玩过。 +HTML ERRORS - PAGE_NOT_FOUND_404 || 页面不存在。 +HTML ERRORS - UNAUTHORIZED_401 || 未认证 +HTML ERRORS - UNKNOWN_PAGE_404 || 请确保阁下正通过命令所给出的链接访问,示例:

/player/玩家名
/server/服务器名

+HTML ERRORS - UUID_404 || 未在数据库中找到玩家的 UUID。 In Depth Help - /plan ? || §2/plan - 主命令\§f 用于访问所有子命令及帮助\§7 /plan - 列出子命令\§7 /plan <子命令> ? - 详细帮助 In Depth Help - /plan analyze ? || §2分析命令\§f 用于刷新分析缓存及访问结果页面\§7 /plan status 可用于在网页在线时检查分析状态fen.\§7 别名:analyze, analyse, analysis, a In Depth Help - /plan inspect ? || §2检视命令\§f 用于获取用户检视页链接。\§7 个人检视页可通过输入 /plan inspect 访问\§7 别名:/plan <名称> In Depth Help - /plan manage ? || §2管理命令\§f 用于管理插件数据库。\§7 别名:/plan m\§7 /plan m - Auflistung der Unterbefehle\§7 /plan m <子命令> ? - 详细帮助 -In Depth Help - /plan manage backup ? || > §2Backup Subcommand\ Creates a new SQLite database (.db file) with contents of currently active database in the Plan plugin folder. +In Depth Help - /plan manage backup ? || > §2备份命令\ 用于建立新 SQLite 数据库(.db 文件)并包含当前在计划插件文件夹中所有的活跃数据库内容。 In Depth Help - /plan manage clear ? || §2管理清除命令\§f 用于清除活跃数据库中的所有数据。\§7 插件在清理完毕后应被重载。\§7 别名:/plan pl -In Depth Help - /plan manage con ? || > §2Connection Debug Subcommand\ Used to debug connections in the network.\ Sends a request to each server in the database. -In Depth Help - /plan manage disable ? || > §2Disable Subcommand\ Can disable parts of the plugin until next reload.\ Accepted arguments:\ §2kickcount §fDisables kick counts in case /kickall is used on shutdown macro. +In Depth Help - /plan manage con ? || > §2调试连接命令\ 用于调试网络间的连接。\ 向数据库中的每个服务器发送请求。 +In Depth Help - /plan manage disable ? || > §2禁用命令\ 用于在下次重新载入之前禁用插件的部分特性。\ 接受的参数:\ §2kickcount §f禁用在关闭服务器时 /kickall 的踢出计数。 In Depth Help - /plan manage import ? || §2管理导入命令\§f 用于从其它来源导入数据\§7 在导入过程中将禁用数据分析。 -In Depth Help - /plan manage move ? || > §2Move Subcommand\ Move data from SQLite to MySQL or other way around.\ Target database is cleared before transfer. +In Depth Help - /plan manage move ? || > §2移动指令\ 将数据从 SQLite 移动至 MySQL,反之亦然。\ 目标数据库将在转移前被清除。 In Depth Help - /plan manage remove ? || §2管理移除命令\§f 用于从活跃数据库中移除用户数据。 -In Depth Help - /plan manage restore ? || > §2Restore Subcommand\ Restore a previous backup SQLite database (.db file)\ You can also restore database.db from another server to MySQL.\ Target database is cleared before transfer. -In Depth Help - /plan manage setup ? || > §2Setup Subcommand\ Set-up a connection between Bungee and this server for network functionality.\ BungeeAddress can be found in the enable log on console when Plan enables on Bungee. -In Depth Help - /plan network ? || > §2Network Command\ Displays link to the network page.\ If not on a network, this page displays the server page. -In Depth Help - /plan players ? || > §2Players Command\ Displays link to the players page. +In Depth Help - /plan manage restore ? || > §2恢复命令\ 从先前备份的 SQLite 数据库中恢复数据(.db 文件)\ 阁下也可以从其他服务器中恢复 database.db 到 MySQL。\ 目标数据库将在传输前被清除。 +In Depth Help - /plan manage setup ? || > §2安装命令\ 设置 Bungee 与此服务器之间的网络连接。\ Bungee 地址可在计划于 Bungee 上启动时的控制台日志中找到。 +In Depth Help - /plan network ? || > §2网络命令\ 显示到网络页的链接。\ 若不在群组网络上,此页面将显示为服务器页面。 +In Depth Help - /plan players ? || > §2玩家命令\ 显示到玩家页的链接。 In Depth Help - /plan qinspect ? || §2快速检视命令\§f 用于获取游戏内关于检视的信息。\§7 相比检视网页有着更少的信息。\§7 别名:/plan qi -In Depth Help - /plan reload ? || > §2Reload Command\ Restarts the plugin using onDisable and onEnable.\ §bDoes not support swapping jar on the fly +In Depth Help - /plan reload ? || > §2重载命令\ 使用 onDisable 与 onEnable 重新载入插件。\ §b不支持运行时热切换插件 In Depth Help - /plan search ? || §2搜索命令\§f 用于获取匹配特定参数的玩家名列表。\§7 示例:/plan search 123 - 搜索名称中包含 123 的所有玩家。 -In Depth Help - /plan servers ? || > §2Servers Command\ Displays list of Plan servers in the Database.\ Can be used to debug issues with database registration on a network. -In Depth Help - /plan update ? || > §2Update Command\ Used to update the plugin on the next shutdown\ /plan update - Changelog link\ /plan update -u - Schedule update to happen on all network servers that are online, next time they reboot.\ /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet. -In Depth Help - /plan web ? || < §2Web User Manage Command.\ §2/plan web §fList subcommands\ §2/plan web ? §fIn Depth help -In Depth Help - /plan web register ? || > §2Register Subcommand\ Registers a new Web User.\ Registering a user for another player requires plan.webmanage permission.\ Passwords are hashed with PBKDF2 (64,000 iterations of SHA1) using a cryptographically-random salt. -In Depth Help - /planbungee disable ? || > §2Disable Command\ Runs onDisable on PlanBungee.\ Plugin can be enabled with /planbungee reload afterwards.\ §bDoes not support swapping jar on the fly -In Depth Help - /planbungee setup ? || > §2Set-up toggle Command\ Toggles set-up mode on Bungee.\ Safeguard against unauthorized MySQL snooping with another server. +In Depth Help - /plan servers ? || > §2服务器命令\ 显示数据库中的计划服务器列表。\ 可用于调试在网络上数据库注册的问题。 +In Depth Help - /plan update ? || > §2更新命令\ 用于在下次关闭服务器时更新插件\ /plan update - 更新日志链接\ /plan update -u - 在所有在线的网络服务器上预定在下次重新启动时更新。\ /plan update cancel - 取消尚未重启的服务器上的更新。 +In Depth Help - /plan web ? || < §2网页用户管理命令。\ §2/plan web §f列出子命令\ §2/plan web <子命令> ? §f详细帮助 +In Depth Help - /plan web register ? || > §2注册命令\ 注册一位新的网页用户。\ 为其他用户注册需要 plan.webmanage 权限。\ 密码通过使用随机密码盐的 PBKDF2 哈希方法加密(重复 64000 次 SHA1)。 +In Depth Help - /planbungee disable ? || > §2禁用命令\ 在 PlanBungee 上运行 onDisable。\ 插件之后需要运行 /planbungee reload 以重新启用。\ §b不支持运行时热切换插件 +In Depth Help - /planbungee setup ? || > §2设置开关命令\ 开关 Bungee 上的安装功能。\ 用来防止与其他服务器之间未授权的 MySQL 监听。 Manage - Confirm Overwrite || 数据库 ${0} 中的数据将被覆盖! Manage - Confirm Removal || 数据库 ${0} 中的数据将被移除! Manage - Fail || > §c[计划] 处理数据时发生错误! ${0} Manage - Fail File not found || > §c[计划] 备份文件不存在! ${0} -Manage - Fail Incorrect Database || > §c'${0}' is not a supported database. -Manage - Fail No Importer || §eImporter '${0}' doesn't exist +Manage - Fail Incorrect Database || > §c'${0}' 不是一个支持的数据库。 +Manage - Fail No Importer || §e导入器 '${0}' 不存在 Manage - Fail Same Database || > §c[计划] 无法移动至相同的数据库! Manage - Fail, Confirmation || > §c[计划] 请添加 -a 以确认执行!${0} -Manage - Fail, Connection Exception || §eFail reason: -Manage - Fail, No Servers || §cNo Servers found in the database. -Manage - Fail, Old version || §eFail reason: Older Plan version on receiving server -Manage - Fail, Unauthorized || §eFail reason: Unauthorized. Server might be using different database. -Manage - Fail, Unexpected Exception || §eOdd Exception: ${0} -Manage - List Importers || Importers: -Manage - Notify External Url || §eNon-local address, check that port is open -Manage - Remind HotSwap || §e[计划] 请记住要切换至新数据库并重新载入插件 (/plan m hotswap ${0}) +Manage - Fail, Connection Exception || §e失败原因: +Manage - Fail, No Servers || §c未在数据库中找到服务器。 +Manage - Fail, Old version || §e失败原因:接收服务器正运行计划的老版本。 +Manage - Fail, Unauthorized || §e失败原因:未授权。服务器可能使用不同的数据库。 +Manage - Fail, Unexpected Exception || §e异常例外:${0} +Manage - List Importers || 导入器: +Manage - Notify External Url || §e非本地地址,请检查端口是否开放 +Manage - Remind HotSwap || §e[计划] 请记住要切换至新数据库并重新载入插件(/plan m hotswap ${0}) Manage - Start || »§7 正在处理数据··· Manage - Success || §f» §2 成功! -Negative || No -Positive || Yes -Unknown || Unknown -Version - DEV || This is a DEV release. -Version - Latest || You're using the latest version. -Version - New || New Release (${0}) is available ${1} -Version - New (old) || New Version is available at ${0} -Version FAIL - Read info (old) || Failed to check newest version number -Version FAIL - Read versions.txt || Version information could not be loaded from Github/versions.txt -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || WebServer: No Certificate -> Using HTTP-server for Visualization. -WebServer - Notify HTTP User Auth || WebServer: User Authorization Disabled! (Not secure over HTTP) -WebServer - Notify no Cert file || WebServer: Certificate KeyStore File not Found: ${0} -WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? -WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. -WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. \ No newline at end of file +Negative || 否 +Positive || 是 +Unknown || 未知 +Version - DEV || 这是开发者版本。 +Version - Latest || 阁下正使用最新版本。 +Version - New || 新版本(${0})可用 ${1} +Version - New (old) || 新版本在 ${0} 可用 +Version FAIL - Read info (old) || 无法检查最新版本号 +Version FAIL - Read versions.txt || 无法从 Github/versions.txt 处载入版本信息 +Web User Listing || §2${0} §7:§f${1} +WebServer - Notify HTTP || 网页服务器:无证书 -> 正使用 HTTP 服务器提供可视化效果。 +WebServer - Notify HTTP User Auth || 网页服务器:已禁用用户认证!(HTTP 方式不安全) +WebServer - Notify no Cert file || 网页服务器:未找到证书密钥存储文件:${0} +WebServer FAIL - Port Bind || 未成功初始化网页服务器。端口(${0})是否被占用? +WebServer FAIL - SSL Context || 网页服务器:SSL 环境初始化失败。 +WebServer FAIL - Store Load || 网页服务器:SSL 证书载入失败。 \ No newline at end of file From 8da9dc643b4dca95b2f285c7e2706d7448c159b5 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 8 Aug 2018 21:12:42 +0300 Subject: [PATCH 02/18] Added RedisBungee online count #642, split ServerProperties to 3 classes --- Plan/dependency-reduced-pom.xml | 10 +++++ Plan/pom.xml | 13 ++++++ .../store/containers/AnalysisContainer.java | 2 +- .../system/info/server/BukkitServerInfo.java | 4 +- .../system/info/server/BungeeServerInfo.java | 4 +- .../plan/system/info/server/ServerInfo.java | 1 + .../system/info/server/SpongeServerInfo.java | 3 +- .../properties/BukkitServerProperties.java | 25 +++++++++++ .../properties/BungeeServerProperties.java | 27 ++++++++++++ .../info/server/properties/RedisCheck.java | 19 ++++++++ .../RedisPlayersOnlineSupplier.java | 18 ++++++++ .../{ => properties}/ServerProperties.java | 43 ++++++------------- .../properties/SpongeServerProperties.java | 28 ++++++++++++ .../tasks/bungee/BungeeTPSCountTimer.java | 3 +- .../response/pages/DebugPageResponse.java | 2 +- .../plan/utilities/html/HtmlStructure.java | 2 +- 16 files changed, 168 insertions(+), 36 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java rename Plan/src/main/java/com/djrapitops/plan/system/info/server/{ => properties}/ServerProperties.java (66%) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/SpongeServerProperties.java diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 67d6f5663..39b5c60d5 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -145,6 +145,10 @@ sponge-repo https://repo.spongepowered.org/maven + + md_5-releases + http://repo.md-5.net/content/repositories/releases/ + @@ -347,6 +351,12 @@ + + com.imaginarycode.minecraft + RedisBungee + RELEASE + provided + org.mockito mockito-core diff --git a/Plan/pom.xml b/Plan/pom.xml index ef6bcd10b..a6ade7375 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -24,6 +24,11 @@ sponge-repo https://repo.spongepowered.org/maven + + + md_5-releases + http://repo.md-5.net/content/repositories/releases/ + @@ -77,6 +82,14 @@ jar provided + + + com.imaginarycode.minecraft + RedisBungee + RELEASE + jar + provided + diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java index 0396fff06..be17d6d9b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java @@ -13,7 +13,7 @@ import com.djrapitops.plan.data.store.mutators.health.HealthInformation; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.ServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java index 7353f347a..0984066f9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java @@ -9,6 +9,8 @@ import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.info.server.properties.BukkitServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.webserver.WebServerSystem; @@ -29,7 +31,7 @@ public class BukkitServerInfo extends ServerInfo { private Database database; public BukkitServerInfo(Plan plugin) { - this(new ServerProperties(plugin.getServer())); + this(new BukkitServerProperties(plugin.getServer())); } public BukkitServerInfo(ServerProperties serverProperties) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java index c98fa570a..c0658b8fa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java @@ -8,6 +8,8 @@ import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.info.server.properties.BungeeServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plugin.api.utility.log.Log; @@ -22,7 +24,7 @@ import java.util.UUID; public class BungeeServerInfo extends ServerInfo { public BungeeServerInfo(PlanBungee plugin) { - super(new ServerProperties(plugin.getProxy())); + super(new BungeeServerProperties(plugin.getProxy())); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java index c12522cb7..9ba36b991 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java @@ -7,6 +7,7 @@ package com.djrapitops.plan.system.info.server; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plugin.utilities.Verify; import java.util.UUID; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java index 0368e6073..b82b09321 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java @@ -1,10 +1,11 @@ package com.djrapitops.plan.system.info.server; +import com.djrapitops.plan.system.info.server.properties.SpongeServerProperties; import org.spongepowered.api.Sponge; public class SpongeServerInfo extends BukkitServerInfo { public SpongeServerInfo() { - super(new ServerProperties(Sponge.getGame())); + super(new SpongeServerProperties(Sponge.getGame())); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java new file mode 100644 index 000000000..8f664a9ae --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java @@ -0,0 +1,25 @@ +package com.djrapitops.plan.system.info.server.properties; + +import org.bukkit.Server; + +/** + * ServerProperties for Bukkit. + * + * @author Rsl1122 + */ +public class BukkitServerProperties extends ServerProperties { + + public BukkitServerProperties(Server server) { + super( + server.getServerId(), + server.getName(), + server.getPort(), + server.getVersion(), + server.getBukkitVersion(), + server::getIp, + server.getMaxPlayers(), + () -> server.getOnlinePlayers().size() + ); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java new file mode 100644 index 000000000..4f6c2cc39 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java @@ -0,0 +1,27 @@ +package com.djrapitops.plan.system.info.server.properties; + +import com.djrapitops.plan.system.settings.Settings; +import net.md_5.bungee.api.ProxyServer; + +/** + * ServerProperties for Bungee. + *

+ * Supports RedisBungee for Players online getting. + * + * @author Rsl1122 + */ +public class BungeeServerProperties extends ServerProperties { + + public BungeeServerProperties(ProxyServer server) { + super( + server.getServers().toString(), + "BungeeCord", + -1, + server.getVersion(), + server.getVersion(), + Settings.BUNGEE_IP::toString, + server.getConfig().getPlayerLimit(), + RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getOnlineCount + ); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java new file mode 100644 index 000000000..d25fc7a0b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java @@ -0,0 +1,19 @@ +package com.djrapitops.plan.system.info.server.properties; + +/** + * Utility class for checking if RedisBungee API is available. + * + * @author Rsl1122 + */ +public class RedisCheck { + + public static boolean isClassAvailable() { + try { + Class.forName("com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java new file mode 100644 index 000000000..1d3a2f28a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java @@ -0,0 +1,18 @@ +package com.djrapitops.plan.system.info.server.properties; + +import com.imaginarycode.minecraft.redisbungee.RedisBungee; + +import java.util.function.Supplier; + +/** + * Players online supplier when using RedisBungee. + * + * @author Rsl1122 + */ +public class RedisPlayersOnlineSupplier implements Supplier { + + @Override + public Integer get() { + return RedisBungee.getApi().getPlayerCount(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java similarity index 66% rename from Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerProperties.java rename to Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java index 497663815..cd58e2f7b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerProperties.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java @@ -1,8 +1,5 @@ -package com.djrapitops.plan.system.info.server; +package com.djrapitops.plan.system.info.server.properties; -import com.djrapitops.plan.system.settings.Settings; -import net.md_5.bungee.api.ProxyServer; -import org.bukkit.Server; import org.spongepowered.api.Game; import java.net.InetSocketAddress; @@ -15,7 +12,7 @@ import java.util.function.Supplier; * @author Rsl1122 * @since 3.4.1 */ -public class ServerProperties { +public abstract class ServerProperties { private final String id; private final String name; @@ -27,30 +24,18 @@ public class ServerProperties { private final Supplier onlinePlayers; - public ServerProperties(Server server) { - id = server.getServerId(); - ip = server::getIp; - name = server.getName(); - port = server.getPort(); - version = server.getVersion(); - implVersion = server.getBukkitVersion(); - - maxPlayers = server.getMaxPlayers(); - - onlinePlayers = () -> server.getOnlinePlayers().size(); - } - - public ServerProperties(ProxyServer server) { - id = server.getServers().toString(); - ip = Settings.BUNGEE_IP::toString; - name = "BungeeCord"; - port = -1; - version = server.getVersion(); - implVersion = server.getVersion(); - - maxPlayers = server.getConfig().getPlayerLimit(); - - onlinePlayers = server::getOnlineCount; + protected ServerProperties( + String id, String name, int port, + String version, String implVersion, + Supplier ip, int maxPlayers, Supplier onlinePlayers) { + this.id = id; + this.name = name; + this.port = port; + this.version = version; + this.implVersion = implVersion; + this.ip = ip; + this.maxPlayers = maxPlayers; + this.onlinePlayers = onlinePlayers; } public ServerProperties(Game game) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/SpongeServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/SpongeServerProperties.java new file mode 100644 index 000000000..1e9a4121b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/SpongeServerProperties.java @@ -0,0 +1,28 @@ +package com.djrapitops.plan.system.info.server.properties; + +import org.spongepowered.api.Game; + +import java.net.InetSocketAddress; + +/** + * ServerProperties for Sponge. + * + * @author Rsl1122 + */ +public class SpongeServerProperties extends ServerProperties { + + public SpongeServerProperties(Game game) { + super( + game.getServer().getMotd().toPlain(), + "Sponge", + game.getServer().getBoundAddress().orElseGet(() -> new InetSocketAddress(25565)).getPort(), + game.getPlatform().getMinecraftVersion().getName(), + game.getPlatform().getMinecraftVersion().getName(), + () -> game.getServer().getBoundAddress() + .orElseGet(() -> new InetSocketAddress(25565)) + .getAddress().getHostAddress(), + game.getServer().getMaxPlayers(), + () -> game.getServer().getOnlinePlayers().size() + ); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java index 058ca284e..2d5edb328 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java @@ -3,6 +3,7 @@ package com.djrapitops.plan.system.tasks.bungee; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.tasks.TPSCountTimer; public class BungeeTPSCountTimer extends TPSCountTimer { @@ -13,7 +14,7 @@ public class BungeeTPSCountTimer extends TPSCountTimer { @Override public void addNewTPSEntry(long nanoTime, long now) { - int onlineCount = plugin.getProxy().getOnlineCount(); + int onlineCount = ServerInfo.getServerProperties().getOnlinePlayers(); TPS tps = TPSBuilder.get() .date(now) .skipTPS() diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java index b31b49cb0..6da1cfb01 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java @@ -13,7 +13,7 @@ import com.djrapitops.plan.system.info.connection.ConnectionLog; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.ServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plan.utilities.html.Html; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java index 82206c59b..c787fb606 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java @@ -8,7 +8,7 @@ import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.ServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph; import com.djrapitops.plan.utilities.html.icon.Color; From 59b0452d476a252768a1d8dee5d973fe0c90b84a Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 8 Aug 2018 22:01:36 +0300 Subject: [PATCH 03/18] Added JSON export to /player//raw #620 and /server//raw #506 --- .../data/store/containers/DataContainer.java | 4 ++ .../webserver/pages/PlayerPageHandler.java | 20 ++++-- .../webserver/pages/ServerPageHandler.java | 7 ++ .../webserver/response/cache/PageId.java | 2 + .../response/pages/RawDataResponse.java | 71 +++++++++++++++++++ .../response/pages/RawPlayerDataResponse.java | 17 +++++ .../response/pages/RawServerDataResponse.java | 17 +++++ 7 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java index c2cefb496..96d7ca388 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java @@ -118,4 +118,8 @@ public class DataContainer { public void clear() { map.clear(); } + + public Map getMap() { + return map; + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java index bead14036..922550a12 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java @@ -19,6 +19,7 @@ import com.djrapitops.plan.system.webserver.response.cache.PageId; import com.djrapitops.plan.system.webserver.response.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.RawPlayerDataResponse; import com.djrapitops.plan.utilities.uuid.UUIDUtility; import java.util.List; @@ -41,17 +42,17 @@ public class PlayerPageHandler extends PageHandler { UUID uuid = UUIDUtility.getUUIDOf(playerName); Locale locale = request.getLocale(); + boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); + if (uuid == null) { return notFound(locale.getString(ErrorPageLang.UUID_404)); } try { if (Database.getActive().check().isPlayerRegistered(uuid)) { - Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); - if (!(response instanceof InspectPageResponse)) { - InfoSystem.getInstance().generateAndCachePlayerPage(uuid); - response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + if (raw) { + return ResponseCache.loadResponse(PageId.RAW_PLAYER.of(uuid), () -> new RawPlayerDataResponse(uuid)); } - return response != null ? response : notFound(locale.getString(ErrorPageLang.NO_SERVERS_404)); + return playerResponseOrNotFound(uuid, locale); } else { return notFound(locale.getString(ErrorPageLang.NOT_PLAYED_404)); } @@ -61,6 +62,15 @@ public class PlayerPageHandler extends PageHandler { return InspectPageResponse.getRefreshing(); } + private Response playerResponseOrNotFound(UUID uuid, Locale locale) throws WebException { + Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + if (!(response instanceof InspectPageResponse)) { + InfoSystem.getInstance().generateAndCachePlayerPage(uuid); + response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + } + return response != null ? response : notFound(locale.getString(ErrorPageLang.NO_SERVERS_404)); + } + private Response notFound(String error) { return ResponseCache.loadResponse(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java index c59029c42..9cd01151a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java @@ -15,6 +15,7 @@ import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.cache.PageId; import com.djrapitops.plan.system.webserver.response.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.system.webserver.response.pages.RawServerDataResponse; import com.djrapitops.plugin.api.Check; import java.util.List; @@ -31,6 +32,12 @@ public class ServerPageHandler extends PageHandler { @Override public Response getResponse(Request request, List target) { UUID serverUUID = getServerUUID(target); + + boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); + if (raw) { + return ResponseCache.loadResponse(PageId.RAW_SERVER.of(serverUUID), () -> new RawServerDataResponse(serverUUID)); + } + Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); if (response != null) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/PageId.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/PageId.java index f1b657004..a5417b6c9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/PageId.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/PageId.java @@ -14,7 +14,9 @@ import java.util.UUID; public enum PageId { SERVER("serverPage:"), + RAW_SERVER("rawServer:"), PLAYER("playerPage:"), + RAW_PLAYER("rawPlayer:"), PLAYERS("playersPage"), ERROR("error:"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java new file mode 100644 index 000000000..cf8ec3446 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java @@ -0,0 +1,71 @@ +package com.djrapitops.plan.system.webserver.response.pages; + +import com.djrapitops.plan.data.store.containers.DataContainer; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.ResponseType; +import com.google.gson.Gson; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Response for sending raw data as JSON when it is inside a DataContainer. + *

+ * This transform class is required to remove Key-Supplier object pollution in the resulting JSON, as well as to remove + * the effects of the caching layer. + * + * @author Rsl1122 + */ +public class RawDataResponse extends Response { + + public RawDataResponse(DataContainer dataContainer) { + super(ResponseType.JSON); + + Map values = mapToNormalMap(dataContainer); + + super.setHeader("HTTP/1.1 200 OK"); + + Gson gson = new Gson(); + super.setContent(gson.toJson(values)); + } + + private Map mapToNormalMap(DataContainer player) { + Map values = new HashMap<>(); + player.getMap().forEach((key, value) -> + { + Object object = value.get(); + if (object instanceof DataContainer) { + object = mapToNormalMap((DataContainer) object); + } + if (object instanceof Map) { + object = handleMap((Map) object); + } + if (object instanceof List) { + object = handleList((List) object); + } + values.put(key.getKeyName(), object); + } + ); + return values; + } + + private List handleList(List object) { + List list = object; + if (list.stream().findAny().orElse(null) instanceof DataContainer) { + return list.stream().map((obj) -> mapToNormalMap((DataContainer) obj)).collect(Collectors.toList()); + } + return list; + } + + private Map handleMap(Map object) { + Map map = object; + if (map.values().stream().findAny().orElse(null) instanceof DataContainer) { + Map newMap = new HashMap<>(); + map.forEach((key, value) -> newMap.put(key, mapToNormalMap((DataContainer) value))); + return newMap; + } + return map; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java new file mode 100644 index 000000000..5e5970c71 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java @@ -0,0 +1,17 @@ +package com.djrapitops.plan.system.webserver.response.pages; + +import com.djrapitops.plan.system.cache.CacheSystem; + +import java.util.UUID; + +/** + * Raw Data JSON response for a Player. + * + * @author Rsl1122 + */ +public class RawPlayerDataResponse extends RawDataResponse { + + public RawPlayerDataResponse(UUID uuid) { + super(CacheSystem.getInstance().getDataContainerCache().getPlayerContainer(uuid)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java new file mode 100644 index 000000000..814198d15 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java @@ -0,0 +1,17 @@ +package com.djrapitops.plan.system.webserver.response.pages; + +import com.djrapitops.plan.system.cache.CacheSystem; + +import java.util.UUID; + +/** + * Raw Data JSON response for a Server. + * + * @author Rsl1122 + */ +public class RawServerDataResponse extends RawDataResponse { + + public RawServerDataResponse(UUID serverUUID) { + super(CacheSystem.getInstance().getDataContainerCache().getAnalysisContainer(serverUUID).getServerContainer()); + } +} \ No newline at end of file From 5de088ca030e9bc94f01b7f04f29068a9a3d8544 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 8 Aug 2018 22:06:48 +0300 Subject: [PATCH 04/18] Added /plan m raw , /planbungee raw commands #620 --- .../plan/command/PlanBungeeCommand.java | 2 + .../plan/command/commands/ManageCommand.java | 1 + .../commands/manage/ManageRawDataCommand.java | 60 +++++++++++++++++++ .../plan/system/locale/lang/CmdHelpLang.java | 3 +- .../plan/system/locale/lang/DeepHelpLang.java | 3 +- 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 8af457fd7..f709dc719 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -3,6 +3,7 @@ package com.djrapitops.plan.command; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; +import com.djrapitops.plan.command.commands.manage.ManageRawDataCommand; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; @@ -41,6 +42,7 @@ public class PlanBungeeCommand extends TreeCmdNode { }; CommandNode[] manageGroup = { new ManageConDebugCommand(plugin), + new ManageRawDataCommand(plugin), new BungeeSetupToggleCommand(plugin), new ReloadCommand(plugin), new DisableCommand(plugin), diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 689771cc4..415888900 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -28,6 +28,7 @@ public class ManageCommand extends TreeCmdNode { super.setColorScheme(plugin.getColorScheme()); setNodeGroups( new CommandNode[]{ + new ManageRawDataCommand(plugin), new ManageMoveCommand(plugin), new ManageBackupCommand(plugin), new ManageRestoreCommand(plugin), diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java new file mode 100644 index 000000000..6cbf86df0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java @@ -0,0 +1,60 @@ +package com.djrapitops.plan.command.commands.manage; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.CmdHelpLang; +import com.djrapitops.plan.system.locale.lang.CommandLang; +import com.djrapitops.plan.system.locale.lang.DeepHelpLang; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.command.CommandNode; +import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.CommandUtils; +import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.utilities.Verify; + +import java.util.Arrays; + +/** + * This manage subcommand is used to remove a single player's data from the + * database. + * + * @author Rsl1122 + */ +public class ManageRawDataCommand extends CommandNode { + + private final Locale locale; + + public ManageRawDataCommand(PlanPlugin plugin) { + super("raw", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); + + locale = plugin.getSystem().getLocaleSystem().getLocale(); + + setArguments(""); + setShortHelp(locale.getString(CmdHelpLang.MANAGE_RAW_DATA)); + setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_RAW_DATA)); + } + + @Override + public void onCommand(ISender sender, String commandLabel, String[] args) { + Verify.isTrue(args.length >= 1, + () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); + + String playerName = MiscUtils.getPlayerName(args, sender, Permissions.MANAGE); + + sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); + // Link + String url = ConnectionSystem.getInstance().getMainAddress() + "/player/" + playerName + "/raw"; + String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); + boolean console = !CommandUtils.isPlayer(sender); + if (console) { + sender.sendMessage(linkPrefix + url); + } else { + sender.sendMessage(linkPrefix); + sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); + } + + sender.sendMessage(">"); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java index 8a228462f..ce3dfba9a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java @@ -39,7 +39,8 @@ public enum CmdHelpLang implements Lang { WEB_LEVEL("Command Help - /plan web level", "Information about permission levels"), WEB_LIST("Command Help - /plan web list", "List Web Users"), WEB_CHECK("Command Help - /plan web check", "Inspect a Web User"), - WEB_DELETE("Command Help - /plan web delete", "Delete a Web User"); + WEB_DELETE("Command Help - /plan web delete", "Delete a Web User"), + MANAGE_RAW_DATA("Command Help - /plan manage raw", "View raw JSON of player data"); private final String identifier; private final String defaultValue; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java index e7f4b498f..b4f3657d4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java @@ -31,7 +31,8 @@ public enum DeepHelpLang implements Lang { MANAGE_RESTORE("In Depth Help - /plan manage restore ?", "> §2Restore Subcommand\\ Restore a previous backup SQLite database (.db file)\\ You can also restore database.db from another server to MySQL.\\ Target database is cleared before transfer."), MANAGE_SETUP("In Depth Help - /plan manage setup ?", "> §2Setup Subcommand\\ Set-up a connection between Bungee and this server for network functionality.\\ BungeeAddress can be found in the enable log on console when Plan enables on Bungee."), - WEB_REGISTER("In Depth Help - /plan web register ?", "> §2Register Subcommand\\ Registers a new Web User.\\ Registering a user for another player requires plan.webmanage permission.\\ Passwords are hashed with PBKDF2 (64,000 iterations of SHA1) using a cryptographically-random salt."); + WEB_REGISTER("In Depth Help - /plan web register ?", "> §2Register Subcommand\\ Registers a new Web User.\\ Registering a user for another player requires plan.webmanage permission.\\ Passwords are hashed with PBKDF2 (64,000 iterations of SHA1) using a cryptographically-random salt."), + MANAGE_RAW_DATA("In Depth Help - /plan manage raw ?", "> §2Raw Data Subcommand\\ Displays link to raw JSON data page.\\ Not available if Plan webserver is not enabled."); private final String identifier; private final String defaultValue; From f4fad3a2777ca71b00c6d62ca529c11f19c12204 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Wed, 8 Aug 2018 22:13:01 +0300 Subject: [PATCH 05/18] Fixed player head display sometimes not working #677 --- Plan/src/main/resources/web/player.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plan/src/main/resources/web/player.html b/Plan/src/main/resources/web/player.html index 1240ac371..152d3e586 100644 --- a/Plan/src/main/resources/web/player.html +++ b/Plan/src/main/resources/web/player.html @@ -285,7 +285,7 @@
+ src="https://cravatar.eu/avatar/${playerName}/100.png">

Player Kills: ${playerKillCount} From 7c3acb03af8c42c3749a57843d0c93e5e0a83daf Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 9 Aug 2018 14:50:49 +0300 Subject: [PATCH 06/18] Updated sqlite test-dependency to reduce JVM crashes on CI --- Plan/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plan/pom.xml b/Plan/pom.xml index a6ade7375..c455094b7 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -129,7 +129,7 @@ org.xerial sqlite-jdbc - 3.21.0.1 + 3.23.1 test From 6ebf221ce340115ab0c9eb6b365a69c5e75d16c8 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 9 Aug 2018 15:14:25 +0300 Subject: [PATCH 07/18] Added bStats to pom, added metrics for Bungee and Sponge --- Plan/dependency-reduced-pom.xml | 16 +- Plan/pom.xml | 32 +- .../main/java/com/djrapitops/plan/Plan.java | 5 +- .../java/com/djrapitops/plan/PlanBungee.java | 3 + .../java/com/djrapitops/plan/PlanSponge.java | 3 + .../plan/utilities/metrics/BStats.java | 73 -- .../plan/utilities/metrics/BStatsBukkit.java | 40 ++ .../plan/utilities/metrics/BStatsBungee.java | 40 ++ .../plan/utilities/metrics/BStatsSponge.java | 35 + .../plan/utilities/metrics/Metrics.java | 627 ------------------ 10 files changed, 164 insertions(+), 710 deletions(-) delete mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStats.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java delete mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/metrics/Metrics.java diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 39b5c60d5..f5d762d20 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -87,6 +87,10 @@ org.slf4j.Logger + + org.bstats + com.djrapitops.plan.utilities.metrics + @@ -146,8 +150,12 @@ https://repo.spongepowered.org/maven - md_5-releases - http://repo.md-5.net/content/repositories/releases/ + md_5-snapshots + http://repo.md-5.net/content/repositories/snapshots/ + + + bstats-repo + http://repo.bstats.org/content/repositories/releases/ @@ -354,7 +362,7 @@ com.imaginarycode.minecraft RedisBungee - RELEASE + 0.3.8-SNAPSHOT provided @@ -380,7 +388,7 @@ org.xerial sqlite-jdbc - 3.21.0.1 + 3.23.1 test diff --git a/Plan/pom.xml b/Plan/pom.xml index c455094b7..0c307b7e6 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -26,8 +26,13 @@ - md_5-releases - http://repo.md-5.net/content/repositories/releases/ + md_5-snapshots + http://repo.md-5.net/content/repositories/snapshots/ + + + + bstats-repo + http://repo.bstats.org/content/repositories/releases/ @@ -86,7 +91,7 @@ com.imaginarycode.minecraft RedisBungee - RELEASE + 0.3.8-SNAPSHOT jar provided @@ -117,6 +122,23 @@ 2.9.0 + + + org.bstats + bstats-bukkit + 1.2 + + + org.bstats + bstats-bungeecord + 1.2 + + + org.bstats + bstats-sponge + 1.2 + + org.mockito @@ -230,6 +252,10 @@ org.slf4j.Logger + + org.bstats + com.djrapitops.plan.utilities.metrics + diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index f1619c650..c39d10e6d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -27,7 +27,7 @@ import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.processing.importing.ImporterManager; import com.djrapitops.plan.system.processing.importing.importers.OfflinePlayerImporter; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; -import com.djrapitops.plan.utilities.metrics.BStats; +import com.djrapitops.plan.utilities.metrics.BStatsBukkit; import com.djrapitops.plugin.BukkitPlugin; import com.djrapitops.plugin.StaticHolder; import com.djrapitops.plugin.api.Benchmark; @@ -70,8 +70,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin { ImporterManager.registerImporter(new OfflinePlayerImporter()); - BStats bStats = new BStats(this); - bStats.registerMetrics(); + new BStatsBukkit(this).registerMetrics(); Log.debug("Verbose debug messages are enabled."); Benchmark.stop("Enable", "Enable"); diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java index 1c5704843..f64a97822 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java @@ -10,6 +10,7 @@ import com.djrapitops.plan.system.BungeeSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; +import com.djrapitops.plan.utilities.metrics.BStatsBungee; import com.djrapitops.plugin.BungeePlugin; import com.djrapitops.plugin.StaticHolder; import com.djrapitops.plugin.api.Benchmark; @@ -43,6 +44,8 @@ public class PlanBungee extends BungeePlugin implements PlanPlugin { system.enable(); locale = system.getLocaleSystem().getLocale(); + new BStatsBungee(this).registerMetrics(); + Log.info(locale.getString(PluginLang.ENABLED)); } catch (AbstractMethodError e) { Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 7e8841f9b..8f1d67cd9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -6,6 +6,7 @@ import com.djrapitops.plan.system.SpongeSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; +import com.djrapitops.plan.utilities.metrics.BStatsSponge; import com.djrapitops.plugin.SpongePlugin; import com.djrapitops.plugin.StaticHolder; import com.djrapitops.plugin.api.Benchmark; @@ -57,6 +58,8 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { system.enable(); locale = system.getLocaleSystem().getLocale(); + new BStatsSponge().registerMetrics(); + Log.info(locale.getString(PluginLang.ENABLED)); } catch (AbstractMethodError e) { Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStats.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStats.java deleted file mode 100644 index 751e0fdbd..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStats.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.djrapitops.plan.utilities.metrics; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.HashMap; -import java.util.Map; - -public class BStats { - - private final Plan plugin; - private Metrics metrics; - - public BStats(Plan plugin) { - this.plugin = plugin; - } - - public void registerMetrics() { - Log.logDebug("Enable", "Enabling bStats Metrics."); - if (metrics == null) { - metrics = new Metrics(plugin); - } - registerConfigSettingGraphs(); - } - - private void registerConfigSettingGraphs() { - String serverType = plugin.getServer().getName(); - if ("CraftBukkit".equals(serverType) && Check.isSpigotAvailable()) { - serverType = "Spigot"; - } - String databaseType = Database.getActive().getName(); - String analysisRefreshPeriod = Integer.toString(Settings.ANALYSIS_AUTO_REFRESH.getNumber()); - String themeBase = Settings.THEME_BASE.toString(); - - addStringSettingPie("server_type", serverType); - addStringSettingPie("database_type", databaseType); - addStringSettingPie("analysis_periodic_refresh", analysisRefreshPeriod); - addStringSettingPie("theme_base", themeBase); - - addFeatureBarChart("features"); - } - - private void addStringSettingPie(String id, String setting) { - metrics.addCustomChart(new Metrics.SimplePie(id, () -> setting)); - } - - private void addFeatureBarChart(String id) { - metrics.addCustomChart(new Metrics.AdvancedBarChart(id, () -> { - Map map = new HashMap<>(); - - map.put("HTTPS", isEnabled("HTTPS".equals(WebServer.getInstance().getProtocol().toUpperCase()))); - map.put("HTML Export", isEnabled(Settings.ANALYSIS_EXPORT.isTrue())); - boolean isConnectedToBungee = ConnectionSystem.getInstance().isServerAvailable(); - map.put("BungeeCord Connected", isEnabled(isConnectedToBungee)); - if (isConnectedToBungee) { - map.put("Copy Bungee Config Values", isEnabled(Settings.BUNGEE_COPY_CONFIG.isTrue())); - map.put("Standalone Override", isEnabled(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.isTrue())); - } - map.put("Log Unknown Commands", isEnabled(Settings.LOG_UNKNOWN_COMMANDS.isTrue())); - map.put("Combine Command Aliases", isEnabled(Settings.COMBINE_COMMAND_ALIASES.isTrue())); - return map; - })); - } - - private int[] isEnabled(boolean t) { - return t ? new int[]{1, 0} : new int[]{0, 1}; - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java new file mode 100644 index 000000000..2b3e3a7a3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java @@ -0,0 +1,40 @@ +package com.djrapitops.plan.utilities.metrics; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.api.utility.log.Log; +import org.bstats.bukkit.Metrics; + +public class BStatsBukkit { + + private final Plan plugin; + private Metrics metrics; + + public BStatsBukkit(Plan plugin) { + this.plugin = plugin; + } + + public void registerMetrics() { + Log.logDebug("Enable", "Enabling bStats Metrics."); + if (metrics == null) { + metrics = new Metrics(plugin); + } + registerConfigSettingGraphs(); + } + + private void registerConfigSettingGraphs() { + String serverType = plugin.getServer().getName(); + if ("CraftBukkit".equals(serverType) && Check.isSpigotAvailable()) { + serverType = "Spigot"; + } + String databaseType = Database.getActive().getName(); + + addStringSettingPie("server_type", serverType); + addStringSettingPie("database_type", databaseType); + } + + protected void addStringSettingPie(String id, String setting) { + metrics.addCustomChart(new Metrics.SimplePie(id, () -> setting)); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java new file mode 100644 index 000000000..42a4af38b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java @@ -0,0 +1,40 @@ +package com.djrapitops.plan.utilities.metrics; + +import com.djrapitops.plan.PlanBungee; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plugin.api.utility.log.Log; +import org.bstats.bungeecord.Metrics; + +import java.io.Serializable; + +public class BStatsBungee { + + private final PlanBungee plugin; + private Metrics metrics; + + public BStatsBungee(PlanBungee plugin) { + this.plugin = plugin; + } + + public void registerMetrics() { + Log.logDebug("Enable", "Enabling bStats Metrics."); + if (metrics == null) { + metrics = new Metrics(plugin); + } + registerConfigSettingGraphs(); + } + + private void registerConfigSettingGraphs() { + String serverType = plugin.getProxy().getName(); + String databaseType = Database.getActive().getName(); + + addStringSettingPie("server_type", serverType); + addStringSettingPie("database_type", databaseType); + addStringSettingPie("network_servers", ConnectionSystem.getInstance().getBukkitServers().size()); + } + + protected void addStringSettingPie(String id, Serializable setting) { + metrics.addCustomChart(new Metrics.SimplePie(id, setting::toString)); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java new file mode 100644 index 000000000..327048f5a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java @@ -0,0 +1,35 @@ +package com.djrapitops.plan.utilities.metrics; + +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plugin.api.utility.log.Log; +import org.bstats.sponge.Metrics; + +import javax.inject.Inject; +import java.io.Serializable; + +public class BStatsSponge { + + @Inject + private Metrics metrics; + + public void registerMetrics() { + Log.logDebug("Enable", "Enabling bStats Metrics."); + if (metrics != null) { + registerConfigSettingGraphs(); + } + } + + private void registerConfigSettingGraphs() { + String serverType = "Sponge"; + String databaseType = Database.getActive().getName(); + + addStringSettingPie("server_type", serverType); + addStringSettingPie("database_type", databaseType); + addStringSettingPie("network_servers", ConnectionSystem.getInstance().getBukkitServers().size()); + } + + protected void addStringSettingPie(String id, Serializable setting) { + metrics.addCustomChart(new Metrics.SimplePie(id, setting::toString)); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/Metrics.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/Metrics.java deleted file mode 100644 index 126b34e15..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/Metrics.java +++ /dev/null @@ -1,627 +0,0 @@ -package com.djrapitops.plan.utilities.metrics; - -import com.djrapitops.plugin.api.TimeAmount; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.RegisteredServiceProvider; -import org.bukkit.plugin.ServicePriority; -import org.bukkit.plugin.java.JavaPlugin; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; - -import javax.net.ssl.HttpsURLConnection; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.concurrent.Callable; -import java.util.logging.Level; -import java.util.zip.GZIPOutputStream; - -/** - * bStats collects some data for plugin authors. - *

- * Condition out https://bStats.org/ to learn more about bStats! - */ -@SuppressWarnings("unchecked") -public class Metrics { - - // The version of this bStats class - public static final int B_STATS_VERSION = 1; - // The url to which the data is sent - private static final String URL = "https://bStats.org/submitData/bukkit"; - // Should failed requests be logged? - private static boolean logFailedRequests; - // The uuid of the server - private static String serverUUID; - - static { - // You can use the property to disable the check in your test environment - if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { - // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D - final String defaultPackage = new String( - new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); - final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); - // We want to make sure nobody just copy & pastes the example and use the wrong package names - if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) { - throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); - } - } - } - - // The plugin - private final JavaPlugin plugin; - - // A list with all custom charts - private final List charts = new ArrayList<>(); - - public Metrics(JavaPlugin plugin) { - if (plugin == null) { - throw new IllegalArgumentException("Plugin cannot be null!"); - } - this.plugin = plugin; - - // Get the config file - File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); - File configFile = new File(bStatsFolder, "config.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - - // Condition if the config file exists - if (!config.isSet("serverUuid")) { - - // Add default values - config.addDefault("enabled", true); - // Every server gets it's unique random id. - config.addDefault("serverUuid", UUID.randomUUID().toString()); - // Should failed request be logged? - config.addDefault("logFailedRequests", false); - - // Inform the server owners about bStats - config.options().header( - "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + - "To honor their work, you should not disable it.\n" + - "This has nearly no effect on the server performance!\n" + - "Check out https://bStats.org/ to learn more :)" - ).copyDefaults(true); - try { - config.save(configFile); - } catch (IOException ignored) { - /* Ignored */ - } - } - - // Load the data - serverUUID = config.getString("serverUuid"); - logFailedRequests = config.getBoolean("logFailedRequests", false); - if (config.getBoolean("enabled", true)) { - boolean found = false; - // Search for all other bStats Metrics classes to see if we are the first one - for (Class service : Bukkit.getServicesManager().getKnownServices()) { - try { - service.getField("B_STATS_VERSION"); // Our identifier :) - found = true; // We aren't the first - break; - } catch (NoSuchFieldException ignored) { - /* Ignored */ - } - } - // Register our service - Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); - if (!found) { - // We are the first! - startSubmitting(); - } - } - } - - /** - * Sends the data to the bStats server. - * - * @param data The data to send. - * @throws Exception If the request failed. - */ - private static void sendData(JSONObject data) throws Exception { - if (data == null) { - throw new IllegalArgumentException("Data cannot be null!"); - } - if (Bukkit.isPrimaryThread()) { - throw new IllegalAccessException("This method must not be called from the main thread!"); - } - HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); - - // Compress the data to save bandwidth - byte[] compressedData = compress(data.toString()); - - // Add headers - connection.setRequestMethod("POST"); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request - connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format - connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); - - // Send data - connection.setDoOutput(true); - DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); - outputStream.write(compressedData); - outputStream.flush(); - outputStream.close(); - - connection.getInputStream().close(); // We don't care about the response - Just send our data :) - } - - /** - * Gzips the given String. - * - * @param str The string to gzip. - * @return The gzipped String. - * @throws IOException If the compression failed. - */ - private static byte[] compress(final String str) throws IOException { - if (str == null) { - return null; - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - GZIPOutputStream gzip = new GZIPOutputStream(outputStream); - gzip.write(str.getBytes(StandardCharsets.UTF_8)); - gzip.close(); - return outputStream.toByteArray(); - } - - /** - * Adds a custom chart. - * - * @param chart The chart to add. - */ - public void addCustomChart(CustomChart chart) { - if (chart == null) { - throw new IllegalArgumentException("Chart cannot be null!"); - } - charts.add(chart); - } - - /** - * Starts the Scheduler which submits our data every 30 minutes. - */ - private void startSubmitting() { - final Metrics metrics = this; - - final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - if (!plugin.isEnabled()) { // Plugin was disabled - timer.cancel(); - return; - } - // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler - // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) - Bukkit.getScheduler().runTask(plugin, metrics::submitData); - } - }, TimeAmount.MINUTE.ms() * 5, TimeAmount.MINUTE.ms() * 30); - // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start - // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! - // WARNING: Just don't do it! - } - - /** - * Gets the plugin specific data. - * This method is called using Reflection. - * - * @return The plugin specific data. - */ - public JSONObject getPluginData() { - JSONObject data = new JSONObject(); - - String pluginName = plugin.getDescription().getName(); - String pluginVersion = plugin.getDescription().getVersion(); - - data.put("pluginName", pluginName); // Append the name of the plugin - data.put("pluginVersion", pluginVersion); // Append the version of the plugin - JSONArray customCharts = new JSONArray(); - for (CustomChart customChart : charts) { - // Add the data of the custom charts - JSONObject chart = customChart.getRequestJsonObject(); - if (chart == null) { // If the chart is null, we skip it - continue; - } - customCharts.add(chart); - } - data.put("customCharts", customCharts); - - return data; - } - - /** - * Gets the server specific data. - * - * @return The server specific data. - */ - private JSONObject getServerData() { - // Minecraft specific data - int playerAmount; - try { - // Around MC 1.8 the return type was changed to a collection from an array, - // This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; - Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); - playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) - ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() - : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; - } catch (Exception e) { - playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed - } - int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; - String bukkitVersion = org.bukkit.Bukkit.getVersion(); - bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); - - // OS/Java specific data - String javaVersion = System.getProperty("java.version"); - String osName = System.getProperty("os.name"); - String osArch = System.getProperty("os.arch"); - String osVersion = System.getProperty("os.version"); - int coreCount = Runtime.getRuntime().availableProcessors(); - - JSONObject data = new JSONObject(); - - data.put("serverUUID", serverUUID); - - data.put("playerAmount", playerAmount); - data.put("onlineMode", onlineMode); - data.put("bukkitVersion", bukkitVersion); - - data.put("javaVersion", javaVersion); - data.put("osName", osName); - data.put("osArch", osArch); - data.put("osVersion", osVersion); - data.put("coreCount", coreCount); - - return data; - } - - /** - * Collects the data and sends it afterwards. - */ - private void submitData() { - final JSONObject data = getServerData(); - - JSONArray pluginData = new JSONArray(); - // Search for all other bStats Metrics classes to get their plugin data - for (Class service : Bukkit.getServicesManager().getKnownServices()) { - try { - service.getField("B_STATS_VERSION"); // Our identifier :) - - for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { - try { - pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider())); - } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { - /* Ignored */ - } - } - } catch (NoSuchFieldException ignored) { - /* Ignored */ - } - } - - data.put("plugins", pluginData); - - // Create a new thread for the connection to the bStats server - new Thread(() -> { - try { - // Send the data - sendData(data); - } catch (Exception e) { - // Something went wrong! :( - if (logFailedRequests) { - plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); - } - } - }).start(); - } - - public abstract static class CustomChart { - - final String chartId; - - CustomChart(String chartId) { - if (chartId == null || chartId.isEmpty()) { - throw new IllegalArgumentException("ChartId cannot be null or empty!"); - } - this.chartId = chartId; - } - - private JSONObject getRequestJsonObject() { - JSONObject chart = new JSONObject(); - chart.put("chartId", chartId); - try { - JSONObject data = getChartData(); - if (data == null) { - // If the data is null we don't send the chart. - return null; - } - chart.put("data", data); - } catch (Exception e) { - if (logFailedRequests) { - Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, e); - } - return null; - } - return chart; - } - - protected abstract JSONObject getChartData() throws Exception; - - } - - public static class SimplePie extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimplePie(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - String value = callable.call(); - if (value == null || value.isEmpty()) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - } - - public static class AdvancedPie extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedPie(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - public static class DrilldownPie extends CustomChart { - - private final Callable>> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public DrilldownPie(String chartId, Callable>> callable) { - super(chartId); - this.callable = callable; - } - - @Override - public JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JSONObject value = new JSONObject(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - value.put(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - values.put(entryValues.getKey(), value); - } - } - if (reallyAllSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - public static class SingleLineChart extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SingleLineChart(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - int value = callable.call(); - if (value == 0) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - - } - - public static class MultiLineChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public MultiLineChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } - - public static class SimpleBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimpleBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - for (Map.Entry entry : map.entrySet()) { - JSONArray categoryValues = new JSONArray(); - categoryValues.add(entry.getValue()); - values.put(entry.getKey(), categoryValues); - } - data.put("values", values); - return data; - } - - } - - public static class AdvancedBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - continue; // Skip this invalid - } - allSkipped = false; - JSONArray categoryValues = new JSONArray(); - for (int categoryValue : entry.getValue()) { - categoryValues.add(categoryValue); - } - values.put(entry.getKey(), categoryValues); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } -} From bc79d72fea96e3ef8ecac11e8791f052c4ed40ad Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 9 Aug 2018 15:29:08 +0300 Subject: [PATCH 08/18] Fixed nickname data truncation on MySQL --- .../java/com/djrapitops/plan/data/store/objects/Nickname.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java b/Plan/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java index 60fa052d0..c6972c9ca 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java @@ -21,7 +21,7 @@ public class Nickname implements DateHolder { } public String getName() { - return name; + return name.length() <= 75 ? name : name.substring(0, 74); } @Override From b96efc7f9295dfe9638284377a2a14821b09f40f Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:18:42 +0300 Subject: [PATCH 09/18] Attempt to fix #680 with connection timeouts --- .../system/info/connection/ConnectionOut.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java index 36da124b8..1a8791442 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java @@ -10,6 +10,7 @@ import com.djrapitops.plan.system.info.request.InfoRequestWithVariables; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import org.apache.http.client.config.RequestConfig; @@ -29,6 +30,7 @@ import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.util.Map; +import java.util.Properties; import java.util.UUID; /** @@ -42,6 +44,17 @@ public class ConnectionOut { private final UUID serverUUID; private final InfoRequest infoRequest; + static { + try { + Properties properties = System.getProperties(); + properties.setProperty("sun.net.client.defaultConnectTimeout", Long.toString(TimeAmount.MINUTE.ms())); + properties.setProperty("sun.net.client.defaultReadTimeout", Long.toString(TimeAmount.MINUTE.ms())); + properties.setProperty("sun.net.http.retryPost", Boolean.toString(false)); + } catch (Exception e) { + e.printStackTrace(); + } + } + /** * Constructor. * @@ -118,10 +131,12 @@ public class ConnectionOut { private void prepareRequest(HttpPost post, String parameters) { RequestConfig requestConfig = RequestConfig.custom() - .setConnectionRequestTimeout(10000) + .setConnectionRequestTimeout(5000) + .setSocketTimeout(10000) + .setConnectTimeout(9000) + .setRedirectsEnabled(true) .setRelativeRedirectsAllowed(true) .setContentCompressionEnabled(true) - .setMaxRedirects(1) .build(); post.setConfig(requestConfig); From 76040c1177ae2a7cdfa4c9981acffd51d339f0ac Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:20:35 +0300 Subject: [PATCH 10/18] Fixed #679 (Null locale) --- Plan/src/main/java/com/djrapitops/plan/Plan.java | 2 +- Plan/src/main/java/com/djrapitops/plan/PlanBungee.java | 2 +- Plan/src/main/java/com/djrapitops/plan/PlanSponge.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index c39d10e6d..13418bb04 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -65,8 +65,8 @@ public class Plan extends BukkitPlugin implements PlanPlugin { try { Benchmark.start("Enable"); system = new BukkitSystem(this); - system.enable(); locale = system.getLocaleSystem().getLocale(); + system.enable(); ImporterManager.registerImporter(new OfflinePlayerImporter()); diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java index f64a97822..9eb8aca1e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java @@ -41,8 +41,8 @@ public class PlanBungee extends BungeePlugin implements PlanPlugin { super.onEnable(); try { system = new BungeeSystem(this); - system.enable(); locale = system.getLocaleSystem().getLocale(); + system.enable(); new BStatsBungee(this).registerMetrics(); diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 8f1d67cd9..d1e5fc3f4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -53,10 +53,10 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { @Override public void onEnable() { super.onEnable(); - system = new SpongeSystem(this); try { - system.enable(); + system = new SpongeSystem(this); locale = system.getLocaleSystem().getLocale(); + system.enable(); new BStatsSponge().registerMetrics(); From e525e0c5db411612cc26363acc713fbfb1dda56f Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:22:43 +0300 Subject: [PATCH 11/18] Ensured Processing ExecutorServices shut down --- .../djrapitops/plan/system/processing/Processing.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java index ac2326af6..35a039693 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java @@ -143,6 +143,16 @@ public class Processing implements SubSystem { Log.toLog(this.getClass(), e); } } + if (!nonCriticalExecutor.isTerminated()) { + try { + nonCriticalExecutor.awaitTermination(1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + nonCriticalExecutor.shutdownNow(); + } + } + if (!criticalExecutor.isTerminated()) { + criticalExecutor.shutdownNow(); + } Log.info(locale.get().getString(PluginLang.DISABLED_PROCESSING_COMPLETE)); } } From 23c8c0769f641675f6706ab5741ad436561a06ee Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:26:14 +0300 Subject: [PATCH 12/18] Attempt to fix #678 by changing RegisterProcessor to a task --- .../plan/system/listeners/bukkit/PlayerOnlineListener.java | 3 ++- .../plan/system/listeners/sponge/SpongePlayerListener.java | 3 ++- .../processing/processors/player/RegisterProcessor.java | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java index 23d34756a..7a3db9509 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java @@ -8,6 +8,7 @@ import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdatePro import com.djrapitops.plan.system.processing.processors.player.*; import com.djrapitops.plugin.api.systems.NotificationCenter; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -96,7 +97,7 @@ public class PlayerOnlineListener implements Listener { SessionCache.getInstance().cacheSession(uuid, new Session(uuid, time, world, gm)); - Processing.submit( + RunnableFactory.createNew("Player Register: " + uuid, new RegisterProcessor(uuid, player::getFirstPlayed, playerName, new IPUpdateProcessor(uuid, address, time), new NameProcessor(uuid, playerName, displayName), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java index a302f2bd2..3742c8ff8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java @@ -8,6 +8,7 @@ import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdatePro import com.djrapitops.plan.system.processing.processors.player.*; import com.djrapitops.plugin.api.systems.NotificationCenter; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.RunnableFactory; import org.spongepowered.api.Sponge; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.entity.living.player.Player; @@ -99,7 +100,7 @@ public class SpongePlayerListener { SessionCache.getInstance().cacheSession(uuid, new Session(uuid, time, world, gm)); - Processing.submit( + RunnableFactory.createNew("Player Register: " + uuid, new RegisterProcessor(uuid, () -> time, playerName, new IPUpdateProcessor(uuid, address, time), new NameProcessor(uuid, playerName, displayName), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java index 2cc024848..c0487ebee 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java @@ -5,8 +5,8 @@ package com.djrapitops.plan.system.processing.processors.player; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.processing.CriticalRunnable; import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.utilities.Verify; import java.util.UUID; @@ -17,7 +17,7 @@ import java.util.function.Supplier; * * @author Rsl1122 */ -public class RegisterProcessor implements CriticalRunnable { +public class RegisterProcessor extends AbsRunnable { private final UUID uuid; private final Supplier registered; @@ -25,6 +25,7 @@ public class RegisterProcessor implements CriticalRunnable { private final Runnable[] afterProcess; public RegisterProcessor(UUID uuid, Supplier registered, String name, Runnable... afterProcess) { + super(RegisterProcessor.class.getSimpleName()); this.uuid = uuid; this.registered = registered; this.name = name; @@ -46,6 +47,7 @@ public class RegisterProcessor implements CriticalRunnable { for (Runnable runnable : afterProcess) { Processing.submit(runnable); } + cancel(); } } } From d4f3e75f0e20a39e9b12f8d8bf67ca01bac7ddcd Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:40:04 +0300 Subject: [PATCH 13/18] Fixed Nickname LastSeen Patch Application --- .../database/databases/sql/patches/NicknameLastSeenPatch.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java index 51c6a480e..a45bc697b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java @@ -4,7 +4,6 @@ import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.system.database.databases.sql.SQLDB; import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement; import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement; -import com.djrapitops.plan.system.database.databases.sql.tables.GeoInfoTable; import com.djrapitops.plan.system.database.databases.sql.tables.NicknamesTable; import com.djrapitops.plan.system.database.databases.sql.tables.UserIDTable; @@ -21,7 +20,7 @@ public class NicknameLastSeenPatch extends Patch { @Override public boolean hasBeenApplied() { - return hasColumn(GeoInfoTable.TABLE_NAME, GeoInfoTable.Col.LAST_USED.get()); + return hasColumn(NicknamesTable.TABLE_NAME, NicknamesTable.Col.LAST_USED.get()); } @Override From 8e81560c0eae6f39971e6760b7426d79d88172f9 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 10 Aug 2018 09:46:23 +0300 Subject: [PATCH 14/18] Fixed players not registering at all --- .../plan/system/listeners/bukkit/PlayerOnlineListener.java | 2 +- .../plan/system/listeners/sponge/SpongePlayerListener.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java index 7a3db9509..c28f0f4a8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java @@ -103,7 +103,7 @@ public class PlayerOnlineListener implements Listener { new NameProcessor(uuid, playerName, displayName), new PlayerPageUpdateProcessor(uuid) ) - ); + ).runTaskAsynchronously(); Processing.submit(new NetworkPageUpdateProcessor()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java index 3742c8ff8..d0f4c478c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java @@ -106,7 +106,7 @@ public class SpongePlayerListener { new NameProcessor(uuid, playerName, displayName), new PlayerPageUpdateProcessor(uuid) ) - ); + ).runTaskAsynchronously(); Processing.submit(new NetworkPageUpdateProcessor()); } From 84ccaabbe4a0d3508f95af71dc4c9a344cccff78 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 11 Aug 2018 11:35:23 +0300 Subject: [PATCH 15/18] Fixed /plan m setup false negative on success #681 --- .../system/info/request/SaveDBSettingsRequest.java | 10 +++++++++- .../system/info/request/SendDBSettingsRequest.java | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java index 5d321c4b0..078f7ea6e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java @@ -12,7 +12,10 @@ import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse; import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; import java.util.Map; @@ -64,7 +67,12 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S Log.info("----------------------------------"); return DefaultResponses.SUCCESS.get(); } finally { - PlanPlugin.getInstance().reloadPlugin(true); + RunnableFactory.createNew("Bungee Setup Restart Task", new AbsRunnable() { + @Override + public void run() { + PlanPlugin.getInstance().reloadPlugin(true); + } + }).runTaskLater(TimeAmount.SECOND.ticks() * 2L); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java index 353eeaf6e..7362b44b8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java @@ -56,6 +56,9 @@ public class SendDBSettingsRequest extends InfoRequestWithVariables implements S if (Check.isBukkitAvailable()) { return new BadRequestResponse("Not supposed to be called on a Bukkit server"); } + if (Check.isSpongeAvailable()) { + return new BadRequestResponse("Not supposed to be called on a Sponge server"); + } String address = variables.get("address"); Verify.nullCheck(address, () -> new BadRequestException("WebServer Address ('address') not specified in the request.")); From d6f7ff967b9de96629d5bb10c4593b5f611da4cd Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 11 Aug 2018 18:05:16 +0300 Subject: [PATCH 16/18] Reload command now performs things async --- .../plan/command/commands/ReloadCommand.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java index d44233459..4fb703aae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java @@ -10,6 +10,8 @@ import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; /** * This SubCommand is used to reload the plugin. @@ -34,12 +36,17 @@ public class ReloadCommand extends CommandNode { @Override public void onCommand(ISender sender, String commandLabel, String[] args) { - try { - plugin.reloadPlugin(true); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED)); - } - sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE)); + RunnableFactory.createNew("Reload task", new AbsRunnable() { + @Override + public void run() { + try { + plugin.reloadPlugin(true); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED)); + } + sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE)); + } + }).runTaskAsynchronously(); } } From 6bcdc67c1f5240f7f08937b2555e1f05cb862b9b Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 11 Aug 2018 18:09:53 +0300 Subject: [PATCH 17/18] Version bump to 4.4.3 --- Plan/src/main/java/com/djrapitops/plan/PlanSponge.java | 2 +- Plan/src/main/resources/bungee.yml | 2 +- Plan/src/main/resources/plugin.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index d1e5fc3f4..93af49ff4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -24,7 +24,7 @@ import org.spongepowered.api.plugin.Plugin; import java.io.File; import java.io.InputStream; -@Plugin(id = "plan", name = "Plan", version = "4.4.2", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) +@Plugin(id = "plan", name = "Plan", version = "4.4.3", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}) public class PlanSponge extends SpongePlugin implements PlanPlugin { @Inject diff --git a/Plan/src/main/resources/bungee.yml b/Plan/src/main/resources/bungee.yml index c92fc52e9..3d5049815 100644 --- a/Plan/src/main/resources/bungee.yml +++ b/Plan/src/main/resources/bungee.yml @@ -1,4 +1,4 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.PlanBungee -version: 4.4.2 \ No newline at end of file +version: 4.4.3 \ No newline at end of file diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index 7a58e121e..a13aacbab 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 4.4.2 +version: 4.4.3 softdepend: - EssentialsX - Towny From 1e100838c01e88984daeade630edf2e62f10b48f Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 11 Aug 2018 19:01:55 +0300 Subject: [PATCH 18/18] Updated debug page to container caches, added tabs to debug page --- .../plan/data/store/CachingSupplier.java | 8 + .../response/cache/ResponseCache.java | 4 + .../response/pages/DebugPageResponse.java | 151 ++++++++++++++++-- .../utilities/html/structure/TabsElement.java | 5 + 4 files changed, 151 insertions(+), 17 deletions(-) diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java b/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java index 81726eb8b..ec3abff37 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java @@ -37,4 +37,12 @@ public class CachingSupplier implements Supplier { } return cachedValue; } + + public boolean isCached() { + return cachedValue != null; + } + + public long getCacheTime() { + return cacheTime; + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/ResponseCache.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/ResponseCache.java index 7b2a3a433..7960f51ed 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/ResponseCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/cache/ResponseCache.java @@ -4,6 +4,7 @@ import com.djrapitops.plan.system.webserver.response.Response; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.function.Supplier; /** @@ -93,4 +94,7 @@ public class ResponseCache { cache.clear(); } + public static Set getCacheKeys() { + return cache.keySet(); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java index 6da1cfb01..cc62f669b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java @@ -5,19 +5,28 @@ package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.CachingSupplier; +import com.djrapitops.plan.data.store.Key; +import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.data.store.mutators.formatting.Formatter; import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.system.cache.CacheSystem; +import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.connection.ConnectionLog; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.webserver.response.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.utilities.file.FileUtil; import com.djrapitops.plan.utilities.html.Html; +import com.djrapitops.plan.utilities.html.HtmlStructure; import com.djrapitops.plan.utilities.html.icon.Icon; +import com.djrapitops.plan.utilities.html.structure.TabsElement; import com.djrapitops.plugin.api.Benchmark; import com.djrapitops.plugin.api.utility.log.ErrorLogger; import com.djrapitops.plugin.api.utility.log.Log; @@ -28,6 +37,7 @@ import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.nio.charset.Charset; import java.util.*; +import java.util.function.Supplier; /** * WebServer response for /debug-page used for easing issue reporting. @@ -39,27 +49,132 @@ public class DebugPageResponse extends ErrorResponse { public DebugPageResponse() { super.setHeader("HTTP/1.1 200 OK"); super.setTitle(Icon.called("bug") + " Debug Information"); - super.setParagraph(buildParagraph()); + super.setParagraph(buildContent()); replacePlaceholders(); } - private String buildParagraph() { - StringBuilder content = new StringBuilder(); + private String buildContent() { + StringBuilder preContent = new StringBuilder(); String issueLink = Html.LINK_EXTERNAL.parse("https://github.com/Rsl1122/Plan-PlayerAnalytics/issues/new", "Create new issue on Github"); - // Information - content.append("

") - .append(issueLink).append("

") - .append("This page contains debug information for an issue ticket.
You can copy it directly into the issue, the info is pre-formatted.") + String hastebinLink = Html.LINK_EXTERNAL.parse("https://hastebin.com/", "Create a new hastebin paste"); + + preContent.append("

") + .append(HtmlStructure.separateWithDots(issueLink, hastebinLink)).append("

") + .append("This page contains debug information for an issue ticket. You can copy it directly into the issue, the info is pre-formatted.") .append("

"); - appendServerInformation(content); + TabsElement.Tab info = new TabsElement.Tab(Icon.called("server") + " Server Information", createServerInfoContent()); + TabsElement.Tab errors = new TabsElement.Tab(Icon.called("exclamation-circle") + " Errors", createErrorContent()); + TabsElement.Tab debugLog = new TabsElement.Tab(Icon.called("bug") + " Debug Log", createDebugLogContent()); + TabsElement.Tab config = new TabsElement.Tab(Icon.called("cogs") + " Plan Config", createConfigContent()); + TabsElement.Tab caches = new TabsElement.Tab(Icon.called("archive") + " Plan Caches", createCacheContent()); - appendConnectionLog(content); - appendLoggedErrors(content); - appendBenchmarks(content); - appendDebugLog(content); + TabsElement tabs = new TabsElement(info, errors, debugLog, config, caches); + + return preContent + tabs.toHtmlFull(); + } + + private String createCacheContent() { + StringBuilder content = new StringBuilder(); + appendResponseCache(content); + appendSessionCache(content); + appendDataContainerCache(content); + return content.toString(); + } + + private void appendResponseCache(StringBuilder content) { + try { + content.append("
### Cached Responses:

"); + List cacheKeys = new ArrayList<>(ResponseCache.getCacheKeys()); + if (cacheKeys.isEmpty()) { + content.append("Empty"); + } + Collections.sort(cacheKeys); + for (String cacheKey : cacheKeys) { + content.append("- ").append(cacheKey).append("
"); + } + content.append("
"); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void appendSessionCache(StringBuilder content) { + try { + content.append("
### Session Cache:

"); + content.append("UUID | Session Started
") + .append("-- | --
"); + Formatter timeStamp = Formatters.yearLongValue(); + Set> sessions = SessionCache.getActiveSessions().entrySet(); + if (sessions.isEmpty()) { + content.append("Empty"); + } + for (Map.Entry entry : sessions) { + UUID uuid = entry.getKey(); + String start = entry.getValue().getValue(SessionKeys.START).map(timeStamp).orElse("Unknown"); + content.append(uuid.toString()).append(" | ").append(start).append("
"); + } + content.append("
"); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private void appendDataContainerCache(StringBuilder content) { + try { + content.append("
### DataContainer Cache:

"); + + content.append("Key | Is Cached | Cache Time
") + .append("-- | -- | --
"); + Formatter timeStamp = Formatters.yearLongValue(); + Set> dataContainers = CacheSystem.getInstance().getDataContainerCache().getMap().entrySet(); + if (dataContainers.isEmpty()) { + content.append("Empty"); + } + for (Map.Entry entry : dataContainers) { + String keyName = entry.getKey().getKeyName(); + Supplier supplier = entry.getValue(); + if (supplier instanceof CachingSupplier) { + CachingSupplier cachingSupplier = (CachingSupplier) supplier; + boolean isCached = cachingSupplier.isCached(); + String cacheText = isCached ? "Yes" : "No"; + String cacheTime = isCached ? timeStamp.apply(cachingSupplier.getCacheTime()) : "-"; + content.append(keyName).append(" | ").append(cacheText).append(" | ").append(cacheTime).append("
"); + } else { + content.append(keyName).append(" | ").append("Non-caching Supplier").append(" | ").append("-").append("
"); + } + } + content.append("
"); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + private String createConfigContent() { + StringBuilder content = new StringBuilder(); appendConfig(content); + return content.toString(); + } + + private String createDebugLogContent() { + StringBuilder content = new StringBuilder(); + appendDebugLog(content); + return content.toString(); + } + + private String createErrorContent() { + StringBuilder content = new StringBuilder(); + appendLoggedErrors(content); + return content.toString(); + } + + private String createServerInfoContent() { + StringBuilder content = new StringBuilder(); + + appendServerInformation(content); + appendConnectionLog(content); + appendBenchmarks(content); return content.toString(); } @@ -68,12 +183,15 @@ public class DebugPageResponse extends ErrorResponse { try { Map> logEntries = ConnectionLog.getLogEntries(); - content.append("
**Connection Log:**
"); + content.append("
### Connection Log:

"); content.append("Server Address | Request Type | Response | Sent
") .append("-- | -- | -- | --
"); Formatter formatter = Formatters.second(); + if (logEntries.isEmpty()) { + content.append("**No Connections Logged**
"); + } for (Map.Entry> entry : logEntries.entrySet()) { String address = entry.getKey(); Map requests = entry.getValue(); @@ -90,7 +208,7 @@ public class DebugPageResponse extends ErrorResponse { } content.append("
"); - content.append("
**Servers:**
"); + content.append("
### Servers:

"); List servers = ConnectionSystem.getInstance().getBukkitServers(); content.append("Server Name | Address | UUID
") .append("-- | -- | --
"); @@ -195,10 +313,9 @@ public class DebugPageResponse extends ErrorResponse { } } for (String error : errorLines) { - content.append("```
") + content.append("
```
") .append(error) - .append("```
") - .append("- [ ] Fixed
"); + .append("```"); } } else { content.append("**No Errors logged.**
"); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java index d79f97464..6cbe5311b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java @@ -19,6 +19,11 @@ public class TabsElement { this.tabs = tabs; } + public String toHtmlFull() { + String[] navAndContent = toHtml(); + return navAndContent[0] + navAndContent[1]; + } + public String[] toHtml() { StringBuilder nav = new StringBuilder(); StringBuilder content = new StringBuilder();