This commit is contained in:
YuTian 2024-08-03 10:05:51 +08:00
parent 2a715306d3
commit 7ad3076315
81 changed files with 3302 additions and 3233 deletions

View File

@ -1,6 +1,6 @@
<component name="ArtifactManager"> <component name="ArtifactManager">
<artifact type="jar" name="McLiveAPI"> <artifact type="jar" name="McLiveAPI">
<output-path>$PROJECT_DIR$/out/artifacts/McLiveAPI</output-path> <output-path>$PROJECT_DIR$/../../../Desktop/1.18.1s/plugins</output-path>
<root id="archive" name="McLiveAPI.jar"> <root id="archive" name="McLiveAPI.jar">
<element id="module-output" name="McLiveAPI" /> <element id="module-output" name="McLiveAPI" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/fastjson-2.0.43.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/fastjson-2.0.43.jar" path-in-jar="/" />

View File

@ -6,6 +6,21 @@
<option name="name" value="Central Repository" /> <option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" /> <option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="sonatype" />
<option name="name" value="sonatype" />
<option name="url" value="https://oss.sonatype.org/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="public-rpg" />
<option name="name" value="public-rpg" />
<option name="url" value="https://repo.aurora-pixels.com/repository/public-rpg/" />
</remote-repository>
<remote-repository>
<option name="id" value="papermc-repo" />
<option name="name" value="papermc-repo" />
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
</remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="central" /> <option name="id" value="central" />
<option name="name" value="Maven Central repository" /> <option name="name" value="Maven Central repository" />

View File

@ -4,8 +4,10 @@
<facet type="minecraft" name="Minecraft"> <facet type="minecraft" name="Minecraft">
<configuration> <configuration>
<autoDetectTypes> <autoDetectTypes>
<platformType>SPIGOT</platformType> <platformType>PAPER</platformType>
<platformType>ADVENTURE</platformType>
</autoDetectTypes> </autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration> </configuration>
</facet> </facet>
</component> </component>

Binary file not shown.

32
pom.xml
View File

@ -1,4 +1,4 @@
<?xml c="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@ -49,4 +49,34 @@
</resources> </resources>
</build> </build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>public-rpg</id>
<url>https://repo.aurora-pixels.com/repository/public-rpg/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.18.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hamster3.cdapi</groupId>
<artifactId>CDTimeAPI</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project> </project>

View File

@ -1,7 +1,5 @@
package com.io.yutian.livemutually.liveroom; package com.io.yutian.livemutually.liveroom;
import org.bukkit.Bukkit;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -0,0 +1,242 @@
package com.io.yutian.livemutually.manager;
import com.io.yutian.mclive.Main;
import com.io.yutian.mclive.data.database.SqlManager;
import com.io.yutian.mclive.util.ConfigYml;
import com.io.yutian.mclive.util.SqlUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class GiftManager {
private double totalMoney;
private LinkedHashMap<String, Integer> giftMap = new LinkedHashMap<>();
private SqlUtil sqlUtil;
private SqlManager sqlManager;
public GiftManager() {
totalMoney = 0;
giftMap.put("小心心", 1);
giftMap.put("人气票", 1);
giftMap.put("闪耀星辰", 1);
giftMap.put("加油鸭", 1);
giftMap.put("比心兔兔", 1);
giftMap.put("热气球", 1);
giftMap.put("爱你哟", 1);
giftMap.put("天鹅之梦", 1);
giftMap.put("Thuglife", 1);
giftMap.put("粘人小狗", 1);
giftMap.put("粉丝团灯牌", 1);
giftMap.put("大啤酒", 2);
giftMap.put("玫瑰", 1);
giftMap.put("抖音", 1);
giftMap.put("称心如意", 1);
giftMap.put("你最好看", 2);
giftMap.put("助力票", 1);
giftMap.put("荣耀擂鼓", 99);
giftMap.put("宠粉季", 1);
giftMap.put("兔耳朵", 99);
giftMap.put("游戏手柄", 99);
giftMap.put("冰镇西瓜", 99);
giftMap.put("为你闪耀", 9);
giftMap.put("棒棒糖", 9);
giftMap.put("鲜花", 10);
giftMap.put("亲吻", 99);
giftMap.put("跑车", 1200);
giftMap.put("礼花筒", 199);
giftMap.put("捏捏小脸", 99);
giftMap.put("鹿仙子", 99);
giftMap.put("夏威夷花环", 99);
giftMap.put("爱的纸鹤", 99);
giftMap.put("送你花花", 49);
giftMap.put("女神花环", 99);
giftMap.put("鱼你一起", 99);
giftMap.put("真爱玫瑰", 366);
giftMap.put("为你举牌", 199);
giftMap.put("龙抬头", 99);
giftMap.put("花开烂漫", 466);
giftMap.put("比心", 199);
giftMap.put("真的爱你", 520);
giftMap.put("万象烟花", 688);
giftMap.put("私人飞机", 3000);
giftMap.put("浪漫烟花", 599);
giftMap.put("闪亮登场", 460);
giftMap.put("多喝热水", 126);
giftMap.put("一点心意", 266);
giftMap.put("荧光棒", 99);
giftMap.put("娶你回家", 599);
giftMap.put("掌上明珠", 888);
giftMap.put("摧残舞台", 899);
giftMap.put("星星点灯", 268);
giftMap.put("一束花开", 366);
giftMap.put("小傻猪", 299);
giftMap.put("环球旅行车", 650);
giftMap.put("爱的守护", 299);
giftMap.put("好运莲莲鸭", 299);
giftMap.put("日出相伴", 726);
giftMap.put("永生花", 520);
giftMap.put("纸短情长", 921);
giftMap.put("直升机", 2999);
giftMap.put("蝶·连理枝", 280);
giftMap.put("爱情树下", 599);
giftMap.put("灵龙现世", 600);
giftMap.put("爱心煎蛋", 99);
giftMap.put("夏日回忆", 1000);
giftMap.put("抖音1号", 10001);
giftMap.put("繁花秘语", 1314);
giftMap.put("ONE礼挑一", 299);
giftMap.put("重拳出击", 199);
giftMap.put("花落长亭", 1588);
giftMap.put("浪漫恋人", 1999);
giftMap.put("花海泛舟", 2800);
giftMap.put("豪华邮轮", 6000);
giftMap.put("环游世界", 3000);
giftMap.put("蝶·书中情", 750);
giftMap.put("带你去海边", 4500);
giftMap.put("蜜蜂叮叮", 1000);
giftMap.put("奇幻八音盒", 2399);
giftMap.put("光之祝福", 1999);
giftMap.put("消暑罐头车", 1500);
giftMap.put("月色山茶花", 1999);
giftMap.put("为你而来", 1688);
giftMap.put("点亮孤单", 1800);
giftMap.put("浪漫营地", 1699);
giftMap.put("薰衣草庄园", 3300);
giftMap.put("红墙白雪", 1688);
giftMap.put("华灯初上", 5000);
giftMap.put("嘉年华", 30000);
giftMap.put("单车恋人", 1899);
giftMap.put("为爱启航", 10001);
giftMap.put("镜中奇缘", 1500);
giftMap.put("仲夏夜之梦", 8999);
giftMap.put("龙珠纳福", 2388);
giftMap.put("蝶·比翼鸟", 1700);
giftMap.put("无畏守护", 10168);
giftMap.put("壁上飞仙", 4999);
giftMap.put("海上生明月", 4166);
giftMap.put("铁甲柔情", 3800);
giftMap.put("心动丘比特", 4321);
giftMap.put("变形战车", 5500);
giftMap.put("抖音飞艇", 20000);
giftMap.put("冰冻战车", 3000);
giftMap.put("星际玫瑰", 7500);
giftMap.put("奏响人生", 3666);
giftMap.put("摩天大厦", 8222);
giftMap.put("传送门", 2999);
giftMap.put("云中秘境", 13140);
giftMap.put("火龙爆发", 5000);
giftMap.put("福佑万家", 4888);
giftMap.put("天空之镜", 6399);
giftMap.put("情定三生", 9666);
giftMap.put("月下瀑布", 6666);
giftMap.put("金鳞化龙", 9000);
giftMap.put("蝶·化蝶飞", 10999);
giftMap.put("无尽浪漫", 19999);
giftMap.put("云霄大厦", 7888);
giftMap.put("梦幻城堡", 28888);
giftMap.put("真爱永恒", 8999);
giftMap.put("跨时空之恋", 9000);
giftMap.put("炫彩射击", 1888);
giftMap.put("一路有你", 17999);
giftMap.put("浪漫马车", 28888);
giftMap.put("蝶·寄相思", 6800);
giftMap.put("梦回紫禁城", 8666);
giftMap.put("小纸条", 399);
giftMap.put("如意锦囊", 99);
giftMap.put("星光瓶", 900);
giftMap.put("一直陪伴你", 520);
giftMap.put("动次打次", 2999);
giftMap.put("宇宙之心", 18888);
}
public List<String> getGiftNameList() {
return new ArrayList<>(giftMap.keySet());
}
public SqlUtil getSqlUtil() {
return sqlUtil;
}
public SqlManager getSqlManager() {
return sqlManager;
}
public void LinkMySqlData() {
String SQL_Host = "gz-cdb-r9koldtt.sql.tencentcdb.com";
String SQL_Port = "29320";
String SQL_Users = "root";
String SQL_Password = "Pixel@123456";
String SQL_Database = "mclivedata";
sqlManager = new SqlManager();
sqlUtil = new SqlUtil(SQL_Host, SQL_Port, SQL_Database, SQL_Users, SQL_Password);
sqlManager.createTable();
}
public int getGiftMoney(String giftName) {
if (giftMap.get(giftName) == null) {
return 1;
}
return giftMap.get(giftName);
}
public double getTotalMoney() {
return totalMoney;
}
public void defaultTotalMoney() {
if (this.totalMoney <= 0) {
for (Player player : Bukkit.getOnlinePlayers()) {
String name = player.getName();
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
}
}
public void addTotalMoney(String name, int money) {
if (this.totalMoney <= 0) {
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
if (money >= 5000) {
SaveZhuboData(name);
}
this.totalMoney += money;
}
public void addTotalMoney(String name, int money, long amount) {
if (this.totalMoney <= 0) {
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
int newMoney = (int) (money * amount);
if (newMoney >= 5000) {
SaveZhuboData(name);
}
this.totalMoney += newMoney;
}
public void SaveZhuboData(String name) {
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
if (ConfigYml.mysqlState) {
sqlManager.SavePlayerData(tiktok);
}
}
}

View File

@ -1,21 +1,17 @@
package com.io.yutian.livemutually.manager; package com.io.yutian.livemutually.manager;
import cn.hamster3.cdapi.CDTimeAPI;
import com.io.yutian.mclive.*;
import com.io.yutian.pixelliveplugin.PixelLiveAPI; import com.io.yutian.pixelliveplugin.PixelLiveAPI;
import com.io.yutian.verify.AESUtil;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
public class KSLiveRoomManager { public class KSLiveRoomManager {
public static List<Player> livepluginList = new ArrayList<>(); private static List<Player> players = new ArrayList<>();
public static boolean isConnected(Player player) { public static boolean isConnected(Player player) {
if(livepluginList.contains(player)){ if (players.contains(player)) {
return true; return true;
} }
return false; return false;
@ -25,9 +21,13 @@ public class KSLiveRoomManager {
if (!isConnected(player)) { if (!isConnected(player)) {
return; return;
} }
livepluginList.remove(player); players.remove(player);
PixelLiveAPI.disconnect(player); PixelLiveAPI.disconnect(player);
player.sendMessage("§c[系统]§b已断开直播间连接..."); player.sendMessage("§c[系统]§b已断开直播间连接...");
} }
public static List<Player> getPlayers() {
return players;
}
} }

View File

@ -0,0 +1,115 @@
package com.io.yutian.livemutually.manager;
import com.io.yutian.mclive.Main;
import com.io.yutian.mclive.data.UserResourceData;
import com.io.yutian.pixelengine.api.EngineAPI;
import com.io.yutian.pixelengine.api.util.ImageUtil;
import json.JSONObject;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class RankManager {
private static List<String> topCache = new ArrayList<>();
private static Map<String, Long> userDatas = new HashMap<>();
public static void addUserAmount(String userName, long score) {
if (userName == null || userName.isEmpty() || userName.length() == 0) {
return;
}
long amount = userDatas.getOrDefault(userName, score);
userDatas.put(userName, amount + score);
Bukkit.getScheduler().runTaskAsynchronously(Main.plugin, RankManager::update);
save();
}
public static void update() {
List<String> tops = userDatas.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(3)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
if (topCache.isEmpty() || !topCache.equals(tops)) {
topCache = tops;
for (int i = 0; i < 3; i++) {
if (i >= tops.size()) {
return;
}
String name = tops.get(i);
UserResourceData userResourceData = UserManager.getUserResourceData(name);
if (userResourceData != null) {
int finalI = i;
String base64 = ImageUtil.getCacheImageBase64(userResourceData.getNickName(), userResourceData.getAvatarThumbUrl(), (newBase64) -> {
for (Player player : Bukkit.getOnlinePlayers()) {
EngineAPI.getRankAPI().setRankData(player, finalI + 1, newBase64, userResourceData.getLevel());
}
});
for (Player player : Bukkit.getOnlinePlayers()) {
EngineAPI.getRankAPI().setRankData(player, i + 1, base64, userResourceData.getLevel());
}
}
}
}
}
public static long getUserAmount(String userName) {
return userDatas.getOrDefault(userName, 0L);
}
public static void save() {
File file = new File(Main.plugin.getDataFolder(), "rank.yml");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
for (Map.Entry<String, Long> entry : userDatas.entrySet()) {
String key = entry.getKey();
if (key == null || key.isEmpty() || key.length() == 0) {
continue;
}
try {
config.set(key, entry.getValue());
} catch (Exception e) {
}
}
try {
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void load() {
File file = new File(Main.plugin.getDataFolder(), "rank.yml");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
for (String key : config.getKeys(false)) {
userDatas.put(key, config.getLong(key));
}
}
public static void clear() {
File file = new File(Main.plugin.getDataFolder(), "rank.yml");
file.delete();
userDatas.clear();
}
}

View File

@ -1,39 +0,0 @@
package com.io.yutian.livemutually.manager;
import java.util.HashMap;
public class UserData {
private String userName;
// 礼物 礼物数据
private HashMap<String,GiftData> giftData = new HashMap<>();
public UserData(String userName){
this.userName = userName;
this.giftData = new HashMap<>();
}
public String getUserName() {
return userName;
}
// 判断本次赠送礼物是否已送过
public boolean isExitGift(String giftName){
if(giftData.get(giftName) != null){
return true;
}
return false;
}
public GiftData getGiftsData(String giftName){
if(giftData.get(giftName) != null){
return giftData.get(giftName);
}
return null;
}
public void createGiftsData(String giftName,long giftAmount){
long sendTime = System.currentTimeMillis();
giftData.put(giftName,new GiftData(giftName,giftAmount,sendTime));
}
}

View File

@ -0,0 +1,20 @@
package com.io.yutian.livemutually.manager;
import com.io.yutian.mclive.data.UserResourceData;
import java.util.HashMap;
import java.util.Map;
public class UserManager {
private static Map<String, UserResourceData> userResourceDataMap = new HashMap<>();
public static void setUserResourceData(String userName, UserResourceData userResourceData) {
userResourceDataMap.put(userName, userResourceData);
}
public static UserResourceData getUserResourceData(String userName) {
return userResourceDataMap.get(userName);
}
}

View File

@ -1,7 +1,9 @@
package com.io.yutian.mclive; package com.io.yutian.mclive;
import com.io.yutian.livemutually.manager.KSLiveRoomManager; import com.io.yutian.livemutually.manager.KSLiveRoomManager;
import com.io.yutian.mclive.data.GiftManage; import com.io.yutian.livemutually.manager.GiftManager;
import com.io.yutian.livemutually.manager.RankManager;
import com.io.yutian.livemutually.manager.UserManager;
import com.io.yutian.mclive.event.ZhuboAPI; import com.io.yutian.mclive.event.ZhuboAPI;
import com.io.yutian.mclive.listener.JoinGameRoom; import com.io.yutian.mclive.listener.JoinGameRoom;
import com.io.yutian.mclive.listener.LiveAdminGui; import com.io.yutian.mclive.listener.LiveAdminGui;
@ -9,13 +11,14 @@ import com.io.yutian.mclive.listener.SoundsMenu;
import com.io.yutian.mclive.live.LiveEvent; import com.io.yutian.mclive.live.LiveEvent;
import com.io.yutian.mclive.live.ModEvent; import com.io.yutian.mclive.live.ModEvent;
import com.io.yutian.mclive.util.ConfigYml; import com.io.yutian.mclive.util.ConfigYml;
import com.io.yutian.pixelliveplugin.PixelLiveAPI;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -30,44 +33,9 @@ public class Main extends JavaPlugin {
public static Main plugin; public static Main plugin;
public static boolean check_plugin = false; public static boolean check_plugin = false;
public static ConfigYml configYml; public static ConfigYml configYml;
public static GiftManage giftManage; public static GiftManager giftManager;
public static boolean giftStatistics = true; public static boolean giftStatistics = true;
@Override
public void onEnable() {
plugin = this;
SendPluginsAuthorMessage(Bukkit.getConsoleSender());
configYml = new ConfigYml(getConfig());
if (giftStatistics){
giftManage = new GiftManage();
giftManage.LinkMySqlData();
}
addSoundKeyList();
getServer().getPluginManager().registerEvents(new LiveAdminGui(),this);
getServer().getPluginManager().registerEvents(new JoinGameRoom(),this);
getServer().getPluginManager().registerEvents(new ModEvent(),this);
getServer().getPluginManager().registerEvents(new LiveEvent(configYml),this);
getServer().getPluginManager().registerEvents(new SoundsMenu(),this);
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §7当前版本: §ev"+plugin.getDescription().getVersion());
Plugin plugin = getServer().getPluginManager().getPlugin(configYml.getGameMode());
if (plugin != null) {
check_plugin = true;
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §a已激活游戏模式");
if(giftStatistics) {
Bukkit.getScheduler().runTaskTimerAsynchronously(this, new Runnable() {
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
giftManage.SaveZhuboData(player.getName());
}
}
}, 0L, 24000L);
}
} else {
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §c未检测到§a<"+configYml.getGameMode()+">§c游戏插件.");
}
}
public static void addSoundKeyList() { public static void addSoundKeyList() {
List<String> stringList = new ArrayList<>(); List<String> stringList = new ArrayList<>();
stringList.add("youbom"); stringList.add("youbom");
@ -121,11 +89,91 @@ public class Main extends JavaPlugin {
SoundsMenu.soundList.addAll(stringList); SoundsMenu.soundList.addAll(stringList);
} }
public static void SendPluginsAuthorMessage(CommandSender sender) {
sender.sendMessage(" ");
sender.sendMessage("§b ██ ████");
sender.sendMessage("§b ██");
sender.sendMessage("§b██░███▒ ████ ███ ███ ░████▒ ██");
sender.sendMessage("§b███████▒ ████ ██▒▒██ ░██████▒ ██");
sender.sendMessage("§b███ ███ ██ ▒████▒ ██▒ ▒██ ██");
sender.sendMessage("§b██░ ░██ ██ ████ ████████ ██");
sender.sendMessage("§b██ ██ ██ ▒██▒ ████████ ██");
sender.sendMessage("§b██░ ░██ ██ ████ ██ ██");
sender.sendMessage("§b███ ███ ██ ▒████▒ ███░ ▒█ ██▒");
sender.sendMessage("§b███████▒ ████████ ██▒▒██ ░███████ █████");
sender.sendMessage("§b██░███▒ ████████ ███ ███ ░█████▒ ░████");
sender.sendMessage("§b██");
sender.sendMessage("§b█ 弹幕互动引擎 由极光像素工作室提供技术支持!!");
sender.sendMessage("§b█ 如有使用问题可联系售后: §d" + getAuthorFile().getString("author"));
sender.sendMessage("" + getAuthorFile().getString("linemessage"));
}
public static FileConfiguration getAuthorFile() {
File ShopMenufile = new File("plugins/PluginMetrics", "config.yml");
return YamlConfiguration.loadConfiguration(ShopMenufile);
}
public static String HideName(String audience) {
if (audience.length() <= 2) {
return "**";
}
// 获取第一个和第二个字符
char firstChar = audience.charAt(0);
char lastChar = audience.charAt(audience.length() - 1);
// 构建屏蔽后的字符串
StringBuilder maskedString = new StringBuilder();
for (int i = 1; i < audience.length() - 1; i++) {
maskedString.append('*');
}
return String.valueOf(firstChar) + maskedString + lastChar;
}
public static String getMinecraftVersion() {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
return version;
}
@Override
public void onEnable() {
plugin = this;
SendPluginsAuthorMessage(Bukkit.getConsoleSender());
configYml = new ConfigYml(getConfig());
if (giftStatistics) {
giftManager = new GiftManager();
giftManager.LinkMySqlData();
}
addSoundKeyList();
getServer().getPluginManager().registerEvents(new LiveAdminGui(), this);
getServer().getPluginManager().registerEvents(new JoinGameRoom(), this);
getServer().getPluginManager().registerEvents(new ModEvent(), this);
getServer().getPluginManager().registerEvents(new LiveEvent(configYml), this);
getServer().getPluginManager().registerEvents(new SoundsMenu(), this);
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §7当前版本: §ev" + plugin.getDescription().getVersion());
Plugin plugin = getServer().getPluginManager().getPlugin(configYml.getGameMode());
check_plugin = true;
if (plugin != null) {
RankManager.load();
check_plugin = true;
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §a已激活游戏模式");
if (giftStatistics) {
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
giftManager.SaveZhuboData(player.getName());
}
}, 0L, 24000L);
}
} else {
Bukkit.getConsoleSender().sendMessage("§b[整蛊MC直播] §c未检测到§a<" + configYml.getGameMode() + ">§c游戏插件.");
}
}
@Override @Override
public void onDisable() { public void onDisable() {
if (giftStatistics && ConfigYml.mysqlState) { if (giftStatistics && ConfigYml.mysqlState) {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
giftManage.SaveZhuboData(player.getName()); giftManager.SaveZhuboData(player.getName());
} }
} }
} }
@ -151,6 +199,12 @@ public class Main extends JavaPlugin {
sender.sendMessage(""); sender.sendMessage("");
return true; return true;
} }
if (args.length == 1 && args[0].equalsIgnoreCase("test")) {
Player player = (Player) sender;
PixelLiveAPI.connect(player, "127.0.0.1", 9018);
return true;
}
if (args.length == 1 && args[0].equalsIgnoreCase("reload")) { if (args.length == 1 && args[0].equalsIgnoreCase("reload")) {
Main.configYml.ReloadConfig(); Main.configYml.ReloadConfig();
sender.sendMessage("§c[系统]§a配置文件已重载"); sender.sendMessage("§c[系统]§a配置文件已重载");
@ -158,7 +212,7 @@ public class Main extends JavaPlugin {
} }
if (args.length == 1 && args[0].equalsIgnoreCase("save")) { if (args.length == 1 && args[0].equalsIgnoreCase("save")) {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
giftManage.SaveZhuboData(player.getName()); giftManager.SaveZhuboData(player.getName());
} }
sender.sendMessage("§c[系统]§a数据已提交至云数据库."); sender.sendMessage("§c[系统]§a数据已提交至云数据库.");
return true; return true;
@ -177,7 +231,7 @@ public class Main extends JavaPlugin {
} }
if (args.length == 1 && args[0].equalsIgnoreCase("stop")) { if (args.length == 1 && args[0].equalsIgnoreCase("stop")) {
ZhuboAPI.wsRoomIdSame.clear(); ZhuboAPI.wsRoomIdSame.clear();
for (Player player : KSLiveRoomManager.livepluginList) { for (Player player : KSLiveRoomManager.getPlayers()) {
KSLiveRoomManager.disconnect(player); KSLiveRoomManager.disconnect(player);
} }
Bukkit.broadcastMessage("§c[系统]§a已断开所有主播的连接."); Bukkit.broadcastMessage("§c[系统]§a已断开所有主播的连接.");
@ -230,49 +284,4 @@ public class Main extends JavaPlugin {
} }
return false; return false;
} }
public static void SendPluginsAuthorMessage(CommandSender sender) {
sender.sendMessage(" ");
sender.sendMessage("§b ██ ████");
sender.sendMessage("§b ██");
sender.sendMessage("§b██░███▒ ████ ███ ███ ░████▒ ██");
sender.sendMessage("§b███████▒ ████ ██▒▒██ ░██████▒ ██");
sender.sendMessage("§b███ ███ ██ ▒████▒ ██▒ ▒██ ██");
sender.sendMessage("§b██░ ░██ ██ ████ ████████ ██");
sender.sendMessage("§b██ ██ ██ ▒██▒ ████████ ██");
sender.sendMessage("§b██░ ░██ ██ ████ ██ ██");
sender.sendMessage("§b███ ███ ██ ▒████▒ ███░ ▒█ ██▒");
sender.sendMessage("§b███████▒ ████████ ██▒▒██ ░███████ █████");
sender.sendMessage("§b██░███▒ ████████ ███ ███ ░█████▒ ░████");
sender.sendMessage("§b██");
sender.sendMessage("§b█ 弹幕互动引擎 由极光像素工作室提供技术支持!!");
sender.sendMessage("§b█ 如有使用问题可联系售后: §d"+getAuthorFile().getString("author"));
sender.sendMessage(""+getAuthorFile().getString("linemessage"));
}
public static FileConfiguration getAuthorFile(){
File ShopMenufile = new File("plugins/PluginMetrics", "config.yml");
return YamlConfiguration.loadConfiguration(ShopMenufile);
}
public static String HideName(String audience){
if(audience.length() <= 2){
return "**";
}
// 获取第一个和第二个字符
char firstChar = audience.charAt(0);
char lastChar = audience.charAt(audience.length() - 1);
// 构建屏蔽后的字符串
StringBuilder maskedString = new StringBuilder();
for (int i = 1; i < audience.length() - 1; i++) {
maskedString.append('*');
}
return String.valueOf(firstChar) + maskedString + lastChar;
}
public static String getMinecraftVersion() {
String packageName = Bukkit.getServer().getClass().getPackage().getName();
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
return version;
}
} }

View File

@ -1,4 +1,4 @@
package com.io.yutian.livemutually.manager; package com.io.yutian.mclive.data;
public class GiftData { public class GiftData {

View File

@ -1,243 +0,0 @@
package com.io.yutian.mclive.data;
import com.io.yutian.mclive.util.ConfigYml;
import com.io.yutian.mclive.Main;
import com.io.yutian.mclive.util.SqlUtil;
import com.io.yutian.mclive.data.database.SqlManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
public class GiftManage {
private double totalMoney;
private LinkedHashMap<String,Integer> giftMap = new LinkedHashMap<>();
public List<String> getGiftNameList() {
return new ArrayList<>(giftMap.keySet());
}
public GiftManage(){
totalMoney = 0;
giftMap.put("小心心",1);
giftMap.put("人气票",1);
giftMap.put("闪耀星辰",1);
giftMap.put("加油鸭",1);
giftMap.put("比心兔兔",1);
giftMap.put("热气球",1);
giftMap.put("爱你哟",1);
giftMap.put("天鹅之梦",1);
giftMap.put("Thuglife",1);
giftMap.put("粘人小狗",1);
giftMap.put("粉丝团灯牌",1);
giftMap.put("大啤酒",2);
giftMap.put("玫瑰",1);
giftMap.put("抖音",1);
giftMap.put("称心如意",1);
giftMap.put("你最好看",2);
giftMap.put("助力票",1);
giftMap.put("荣耀擂鼓",99);
giftMap.put("宠粉季",1);
giftMap.put("兔耳朵",99);
giftMap.put("游戏手柄",99);
giftMap.put("冰镇西瓜",99);
giftMap.put("为你闪耀",9);
giftMap.put("棒棒糖",9);
giftMap.put("鲜花",10);
giftMap.put("亲吻",99);
giftMap.put("跑车",1200);
giftMap.put("礼花筒",199);
giftMap.put("捏捏小脸",99);
giftMap.put("鹿仙子",99);
giftMap.put("夏威夷花环",99);
giftMap.put("爱的纸鹤",99);
giftMap.put("送你花花",49);
giftMap.put("女神花环",99);
giftMap.put("鱼你一起",99);
giftMap.put("真爱玫瑰",366);
giftMap.put("为你举牌",199);
giftMap.put("龙抬头",99);
giftMap.put("花开烂漫",466);
giftMap.put("比心",199);
giftMap.put("真的爱你",520);
giftMap.put("万象烟花",688);
giftMap.put("私人飞机",3000);
giftMap.put("浪漫烟花",599);
giftMap.put("闪亮登场",460);
giftMap.put("多喝热水",126);
giftMap.put("一点心意",266);
giftMap.put("荧光棒",99);
giftMap.put("娶你回家",599);
giftMap.put("掌上明珠",888);
giftMap.put("摧残舞台",899);
giftMap.put("星星点灯",268);
giftMap.put("一束花开",366);
giftMap.put("小傻猪",299);
giftMap.put("环球旅行车",650);
giftMap.put("爱的守护",299);
giftMap.put("好运莲莲鸭",299);
giftMap.put("日出相伴",726);
giftMap.put("永生花",520);
giftMap.put("纸短情长",921);
giftMap.put("直升机",2999);
giftMap.put("蝶·连理枝",280);
giftMap.put("爱情树下",599);
giftMap.put("灵龙现世",600);
giftMap.put("爱心煎蛋",99);
giftMap.put("夏日回忆",1000);
giftMap.put("抖音1号",10001);
giftMap.put("繁花秘语",1314);
giftMap.put("ONE礼挑一",299);
giftMap.put("重拳出击",199);
giftMap.put("花落长亭",1588);
giftMap.put("浪漫恋人",1999);
giftMap.put("花海泛舟",2800);
giftMap.put("豪华邮轮",6000);
giftMap.put("环游世界",3000);
giftMap.put("蝶·书中情",750);
giftMap.put("带你去海边",4500);
giftMap.put("蜜蜂叮叮",1000);
giftMap.put("奇幻八音盒",2399);
giftMap.put("光之祝福",1999);
giftMap.put("消暑罐头车",1500);
giftMap.put("月色山茶花",1999);
giftMap.put("为你而来",1688);
giftMap.put("点亮孤单",1800);
giftMap.put("浪漫营地",1699);
giftMap.put("薰衣草庄园",3300);
giftMap.put("红墙白雪",1688);
giftMap.put("华灯初上",5000);
giftMap.put("嘉年华",30000);
giftMap.put("单车恋人",1899);
giftMap.put("为爱启航",10001);
giftMap.put("镜中奇缘",1500);
giftMap.put("仲夏夜之梦",8999);
giftMap.put("龙珠纳福",2388);
giftMap.put("蝶·比翼鸟",1700);
giftMap.put("无畏守护",10168);
giftMap.put("壁上飞仙",4999);
giftMap.put("海上生明月",4166);
giftMap.put("铁甲柔情",3800);
giftMap.put("心动丘比特",4321);
giftMap.put("变形战车",5500);
giftMap.put("抖音飞艇",20000);
giftMap.put("冰冻战车",3000);
giftMap.put("星际玫瑰",7500);
giftMap.put("奏响人生",3666);
giftMap.put("摩天大厦",8222);
giftMap.put("传送门",2999);
giftMap.put("云中秘境",13140);
giftMap.put("火龙爆发",5000);
giftMap.put("福佑万家",4888);
giftMap.put("天空之镜",6399);
giftMap.put("情定三生",9666);
giftMap.put("月下瀑布",6666);
giftMap.put("金鳞化龙",9000);
giftMap.put("蝶·化蝶飞",10999);
giftMap.put("无尽浪漫",19999);
giftMap.put("云霄大厦",7888);
giftMap.put("梦幻城堡",28888);
giftMap.put("真爱永恒",8999);
giftMap.put("跨时空之恋",9000);
giftMap.put("炫彩射击",1888);
giftMap.put("一路有你",17999);
giftMap.put("浪漫马车",28888);
giftMap.put("蝶·寄相思",6800);
giftMap.put("梦回紫禁城",8666);
giftMap.put("小纸条",399);
giftMap.put("如意锦囊",99);
giftMap.put("星光瓶",900);
giftMap.put("一直陪伴你",520);
giftMap.put("动次打次",2999);
giftMap.put("宇宙之心",18888);
}
private SqlUtil sqlUtil;
private SqlManager sqlManager;
public SqlUtil getSqlUtil() {
return sqlUtil;
}
public SqlManager getSqlManager() {
return sqlManager;
}
public void LinkMySqlData(){
String SQL_Host = "gz-cdb-r9koldtt.sql.tencentcdb.com";
String SQL_Port = "29320";
String SQL_Users = "root";
String SQL_Password = "Pixel@123456";
String SQL_Database = "mclivedata";
sqlManager = new SqlManager();
sqlUtil = new SqlUtil(SQL_Host,SQL_Port,SQL_Database,SQL_Users,SQL_Password);
sqlManager.createTable();
}
public int getGiftMoney(String giftName){
if(giftMap.get(giftName) == null){
return 1;
}
return giftMap.get(giftName);
}
public double getTotalMoney() {
return totalMoney;
}
public void defaultTotalMoney(){
if(this.totalMoney <= 0) {
for (Player player : Bukkit.getOnlinePlayers()) {
String name = player.getName();
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
}
}
public void addTotalMoney(String name,int money){
if(this.totalMoney <= 0){
if(Main.configYml.getRoomId(name) == null){
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
if(money >= 5000){
SaveZhuboData(name);
}
this.totalMoney += money;
}
public void addTotalMoney(String name,int money, long amount){
if(this.totalMoney <= 0){
if(Main.configYml.getRoomId(name) == null){
return;
}
String tiktok = Main.configYml.getRoomId(name);
this.totalMoney = sqlManager.getZhuboIncome(tiktok) * 10;
}
int newMoney = (int) (money * amount);
if(newMoney >= 5000){
SaveZhuboData(name);
}
this.totalMoney += newMoney;
}
public void SaveZhuboData(String name) {
if (Main.configYml.getRoomId(name) == null) {
return;
}
String tiktok = Main.configYml.getRoomId(name);
if (ConfigYml.mysqlState) {
sqlManager.SavePlayerData(tiktok);
}
}
}

View File

@ -0,0 +1,39 @@
package com.io.yutian.mclive.data;
import java.util.HashMap;
public class UserData {
private String userName;
// 礼物 礼物数据
private HashMap<String, GiftData> giftData = new HashMap<>();
public UserData(String userName) {
this.userName = userName;
this.giftData = new HashMap<>();
}
public String getUserName() {
return userName;
}
// 判断本次赠送礼物是否已送过
public boolean isExitGift(String giftName) {
if (giftData.get(giftName) != null) {
return true;
}
return false;
}
public GiftData getGiftsData(String giftName) {
if (giftData.get(giftName) != null) {
return giftData.get(giftName);
}
return null;
}
public void createGiftsData(String giftName, long giftAmount) {
long sendTime = System.currentTimeMillis();
giftData.put(giftName, new GiftData(giftName, giftAmount, sendTime));
}
}

View File

@ -0,0 +1,29 @@
package com.io.yutian.mclive.data;
import java.io.File;
public class UserResourceData {
private final String nickName;
private String avatarThumbUrl;
private int level;
public UserResourceData(String nickName, String avatarThumbUrl, int level) {
this.nickName = nickName;
this.avatarThumbUrl = avatarThumbUrl;
this.level = level;
}
public String getNickName() {
return nickName;
}
public String getAvatarThumbUrl() {
return avatarThumbUrl;
}
public int getLevel() {
return level;
}
}

View File

@ -1,9 +1,9 @@
package com.io.yutian.mclive.data.database; package com.io.yutian.mclive.data.database;
import com.io.yutian.mclive.Main; import com.io.yutian.mclive.Main;
import com.io.yutian.livemutually.manager.GiftManager;
import com.io.yutian.mclive.data.IPGeolocation; import com.io.yutian.mclive.data.IPGeolocation;
import com.io.yutian.mclive.util.SqlUtil; import com.io.yutian.mclive.util.SqlUtil;
import com.io.yutian.mclive.data.GiftManage;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.time.Instant; import java.time.Instant;
@ -109,11 +109,13 @@ public class SqlManager {
} }
public void SavePlayerData(String tiktok) { public void SavePlayerData(String tiktok) {
if(!Main.giftStatistics){return;} if (!Main.giftStatistics) {
GiftManage giftManage = Main.giftManage; return;
giftManage.defaultTotalMoney(); }
giftManage.addTotalMoney(tiktok,1); GiftManager giftManager = Main.giftManager;
double money = giftManage.getTotalMoney() * 0.1; giftManager.defaultTotalMoney();
giftManager.addTotalMoney(tiktok, 1);
double money = giftManager.getTotalMoney() * 0.1;
String set = "UPDATE `" + table + "` SET " + String set = "UPDATE `" + table + "` SET " +
"`income` = '%income%'," + "`income` = '%income%'," +
"`livetime` = '%livetime%' WHERE `" + table + "`.`tiktok` = '%tiktok%'"; "`livetime` = '%livetime%' WHERE `" + table + "`.`tiktok` = '%tiktok%'";
@ -125,7 +127,7 @@ public class SqlManager {
} }
private SqlUtil getSQL() { private SqlUtil getSQL() {
GiftManage giftManage = Main.giftManage; GiftManager giftManager = Main.giftManager;
return giftManage.getSqlUtil(); return giftManager.getSqlUtil();
} }
} }

View File

@ -20,6 +20,10 @@ public class LiveChatEvents extends Event {
this.content = content; this.content = content;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -37,8 +41,4 @@ public class LiveChatEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -1,6 +1,5 @@
package com.io.yutian.mclive.event; package com.io.yutian.mclive.event;
import com.io.yutian.livemutually.liveroom.User;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -17,6 +16,10 @@ public class LiveConnectEvents extends Event {
this.pluginName = pluginName; this.pluginName = pluginName;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -34,8 +37,4 @@ public class LiveConnectEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -18,6 +18,10 @@ public class LiveEnterEvents extends Event {
this.user = user; this.user = user;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -31,8 +35,4 @@ public class LiveEnterEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -17,6 +17,10 @@ public class LiveFollowEvents extends Event {
this.user = user; this.user = user;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -30,8 +34,4 @@ public class LiveFollowEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -22,6 +22,10 @@ public class LiveGiftEvents extends Event {
this.amount = amount; this.amount = amount;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -43,8 +47,4 @@ public class LiveGiftEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -19,6 +19,10 @@ public class LiveLikeEvents extends Event {
this.count = count; this.count = count;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
@ -36,8 +40,4 @@ public class LiveLikeEvents extends Event {
return handlers; return handlers;
} }
public final static HandlerList getHandlerList() {
return handlers;
}
} }

View File

@ -2,31 +2,34 @@ package com.io.yutian.mclive.event;
import com.io.yutian.livemutually.manager.KSLiveRoomManager; import com.io.yutian.livemutually.manager.KSLiveRoomManager;
import com.io.yutian.mclive.Main; import com.io.yutian.mclive.Main;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public abstract class ZhuboAPI { public abstract class ZhuboAPI {
// 存储Wss主播的直播间id // 存储Wss主播的直播间id
public static HashMap<Player, Boolean> wsRoomIdSame = new HashMap<>(); public static HashMap<Player, Boolean> wsRoomIdSame = new HashMap<>();
public static boolean isWsRoomIdSame(Player player) { public static boolean isWsRoomIdSame(Player player) {
if (wsRoomIdSame.get(player) == null) { if (wsRoomIdSame.get(player) == null) {
return false; return false;
} }
return wsRoomIdSame.get(player); return wsRoomIdSame.get(player);
} }
// 获取主播的连接状态 // 获取主播的连接状态
public static boolean isRoomisConnected(Player zhubo) { public static boolean isRoomisConnected(Player zhubo) {
return KSLiveRoomManager.isConnected(zhubo); return KSLiveRoomManager.isConnected(zhubo);
} }
public static String getRoomLiveName(){return "DouYin";}
public static String getRoomLiveName() {
return "DouYin";
}
//public static String getRoomLiveName(){return "KuaiShou";} //public static String getRoomLiveName(){return "KuaiShou";}
// 获取礼物列表 // 获取礼物列表
public static boolean isGiftNameList(String giftname) { public static boolean isGiftNameList(String giftname) {
for (String gift : Main.giftManage.getGiftNameList()){ for (String gift : Main.giftManager.getGiftNameList()) {
if (giftname.contains(gift)) { if (giftname.contains(gift)) {
return true; return true;
} }

View File

@ -16,6 +16,13 @@ import org.bukkit.event.player.PlayerSwapHandItemsEvent;
public class JoinGameRoom implements Listener { public class JoinGameRoom implements Listener {
public static void SendClickMessage(Player player, String message, String roomId) {
TextComponent tomessage = new TextComponent(message);
tomessage.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://live.douyin.com/" + roomId));
tomessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§9By.极光像素工作室").create()));
player.spigot().sendMessage(tomessage);
}
@EventHandler @EventHandler
public void onSwap(PlayerSwapHandItemsEvent e) { public void onSwap(PlayerSwapHandItemsEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
@ -52,13 +59,6 @@ public class JoinGameRoom implements Listener {
} }
} }
public static void SendClickMessage(Player player,String message,String roomId){
TextComponent tomessage = new TextComponent(message);
tomessage.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://live.douyin.com/"+roomId));
tomessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§9By.极光像素工作室").create()));
player.spigot().sendMessage(tomessage);
}
@EventHandler @EventHandler
public void onQuit(PlayerQuitEvent e) { public void onQuit(PlayerQuitEvent e) {
Player player = e.getPlayer(); Player player = e.getPlayer();

View File

@ -24,115 +24,6 @@ import java.util.List;
public class LiveAdminGui implements Listener { public class LiveAdminGui implements Listener {
public static String invTitle = "我的世界整蛊玩法操作界面"; public static String invTitle = "我的世界整蛊玩法操作界面";
@EventHandler
public void onclick(InventoryClickEvent e){
int rawSlot = e.getRawSlot();
Player player = (Player) e.getWhoClicked();
String playName = player.getName();
Inventory inv = e.getInventory();
if(e.getView().getTitle().equalsIgnoreCase(invTitle)){
e.setCancelled(true);
ItemStack item = e.getCurrentItem();
if(item != null && item.getType() == Material.AIR){
return;
}
if(rawSlot == 1){
player.closeInventory();
if(Main.configYml.getRoomId(playName) == null) {
player.sendMessage("§c[系统]§a请输入命令设置直播间ID: §e/mclive 授权号");
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH,1,1);
}else {
if (ZhuboAPI.isRoomisConnected(player)) {
return;
}
if(System.currentTimeMillis() >= 1723680000000L){ // 2024年8月15日 此插件将过期
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
return;
}
String pluginName = Main.configYml.getGameMode();
String roomId = Main.configYml.getRoomId(playName);
if (AESUtil.isVerifyCheck(player,pluginName,roomId)) {
return;
}
LiveConnectEvents event = new LiveConnectEvents(player,roomId,pluginName);
Bukkit.getPluginManager().callEvent(event);
if(ZhuboAPI.getRoomLiveName().equalsIgnoreCase("KuaiShou")) {
new BukkitRunnable() {
private int i = 0;
private int link = 1;
@Override
public void run() {
if (i >= 4) {
long cdTime = CDTimeAPI.getCD(player.getUniqueId(),"tingcloud_cd");
if(cdTime > 0){
player.sendMessage("§c[系统]§a听云整蛊连接成功.");
cancel();
return;
}
PixelLiveAPI.connect(player, "127.0.0.1", 8765);
player.sendMessage("§c[系统]§a正在尝试§e[第"+link+"次]§a连接.");
link++;
i -= 4;
}
i++;
}
}.runTaskTimerAsynchronously(Main.plugin, 0L, 5L);
player.sendMessage("§c[系统]§a已在为你连接听云整蛊,请不要再次点击.");
} else {
PixelLiveAPI.connect(player,"127.0.0.1",9018);
}
if(Main.giftStatistics){
Main.giftManage.getSqlManager().createAnchorProfile(roomId);
}
Bukkit.getConsoleSender().sendMessage("######CONNECT#####");
player.resetTitle();
Location loc = player.getLocation();
loc.getWorld().playEffect(loc, Effect.MOBSPAWNER_FLAMES, 20);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP,1,1);
}
}
if(rawSlot == 3){
player.closeInventory();
player.performCommand("livegift gui");
player.sendMessage("§c[系统]§a手持任意物品按住 §eSHIFT+Q §a打开界面");
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,1);
}
if(rawSlot == 5){
player.closeInventory();
player.performCommand("gameedit");
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,1);
}
if(rawSlot == 8){
player.closeInventory();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"stop");
}
if(rawSlot == 18){
player.closeInventory();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"mclive stop");
}
if(rawSlot == 22){
SoundsMenu.OpenGui(player,1);
}
if(rawSlot == 20){
player.closeInventory();
if(Main.configYml.getRoomId(playName) == null) {
player.sendMessage("§c[系统]§a请输入命令设置直播间ID: §e/mclive 授权号");
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH,1,1);
}else {
String roomId = Main.configYml.getRoomId(playName);
if (AESUtil.isVerifyCheck(player,Main.configYml.getGameMode(),roomId)) {
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH,1,1);
return;
}
player.sendMessage("§c[系统]§a直播间授权通过,感谢您选择我们的产品.");
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP,1,1);
}
}
}
}
public static HashMap<Player, Integer> offline_zhubo = new HashMap<>(); public static HashMap<Player, Integer> offline_zhubo = new HashMap<>();
public static void OpenGui(Player p) { public static void OpenGui(Player p) {
@ -192,7 +83,6 @@ public class LiveAdminGui implements Listener {
return item; return item;
} }
public static ItemStack Gift_BuChang() { public static ItemStack Gift_BuChang() {
ItemStack item = new ItemStack(Material.PAPER); ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -208,7 +98,6 @@ public class LiveAdminGui implements Listener {
return item; return item;
} }
public static ItemStack Games_Edit() { public static ItemStack Games_Edit() {
ItemStack item = new ItemStack(Material.STONECUTTER); ItemStack item = new ItemStack(Material.STONECUTTER);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -221,6 +110,7 @@ public class LiveAdminGui implements Listener {
item.setItemMeta(meta); item.setItemMeta(meta);
return item; return item;
} }
public static ItemStack Link_Room(Player p) { public static ItemStack Link_Room(Player p) {
ItemStack item = new ItemStack(Material.GOLDEN_SWORD); ItemStack item = new ItemStack(Material.GOLDEN_SWORD);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -297,4 +187,114 @@ public class LiveAdminGui implements Listener {
item.setItemMeta(meta); item.setItemMeta(meta);
return item; return item;
} }
@EventHandler
public void onclick(InventoryClickEvent e) {
int rawSlot = e.getRawSlot();
Player player = (Player) e.getWhoClicked();
String playName = player.getName();
Inventory inv = e.getInventory();
if (e.getView().getTitle().equalsIgnoreCase(invTitle)) {
e.setCancelled(true);
ItemStack item = e.getCurrentItem();
if (item != null && item.getType() == Material.AIR) {
return;
}
if (rawSlot == 1) {
player.closeInventory();
if (Main.configYml.getRoomId(playName) == null) {
player.sendMessage("§c[系统]§a请输入命令设置直播间ID: §e/mclive 授权号");
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH, 1, 1);
} else {
if (ZhuboAPI.isRoomisConnected(player)) {
return;
}
if (System.currentTimeMillis() >= 1723680000000L) { // 2024年8月15日 此插件将过期
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
player.sendMessage("§c[系统]§a当前插件版本太老,请联系作者更新。");
return;
}
String pluginName = Main.configYml.getGameMode();
String roomId = Main.configYml.getRoomId(playName);
if (AESUtil.isVerifyCheck(player, pluginName, roomId)) {
return;
}
LiveConnectEvents event = new LiveConnectEvents(player, roomId, pluginName);
Bukkit.getPluginManager().callEvent(event);
if (ZhuboAPI.getRoomLiveName().equalsIgnoreCase("KuaiShou")) {
new BukkitRunnable() {
private int i = 0;
private int link = 1;
@Override
public void run() {
if (i >= 4) {
long cdTime = CDTimeAPI.getCD(player.getUniqueId(), "tingcloud_cd");
if (cdTime > 0) {
player.sendMessage("§c[系统]§a听云整蛊连接成功.");
cancel();
return;
}
PixelLiveAPI.connect(player, "127.0.0.1", 8765);
player.sendMessage("§c[系统]§a正在尝试§e[第" + link + "次]§a连接.");
link++;
i -= 4;
}
i++;
}
}.runTaskTimerAsynchronously(Main.plugin, 0L, 5L);
player.sendMessage("§c[系统]§a已在为你连接听云整蛊,请不要再次点击.");
} else {
PixelLiveAPI.connect(player, "127.0.0.1", 9018);
}
if (Main.giftStatistics) {
Main.giftManager.getSqlManager().createAnchorProfile(roomId);
}
Bukkit.getConsoleSender().sendMessage("######CONNECT#####");
player.resetTitle();
Location loc = player.getLocation();
loc.getWorld().playEffect(loc, Effect.MOBSPAWNER_FLAMES, 20);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
}
}
if (rawSlot == 3) {
player.closeInventory();
player.performCommand("livegift gui");
player.sendMessage("§c[系统]§a手持任意物品按住 §eSHIFT+Q §a打开界面");
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK, 1, 1);
}
if (rawSlot == 5) {
player.closeInventory();
player.performCommand("gameedit");
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK, 1, 1);
}
if (rawSlot == 8) {
player.closeInventory();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "stop");
}
if (rawSlot == 18) {
player.closeInventory();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "mclive stop");
}
if (rawSlot == 22) {
SoundsMenu.OpenGui(player, 1);
}
if (rawSlot == 20) {
player.closeInventory();
if (Main.configYml.getRoomId(playName) == null) {
player.sendMessage("§c[系统]§a请输入命令设置直播间ID: §e/mclive 授权号");
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH, 1, 1);
} else {
String roomId = Main.configYml.getRoomId(playName);
if (AESUtil.isVerifyCheck(player, Main.configYml.getGameMode(), roomId)) {
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH, 1, 1);
return;
}
player.sendMessage("§c[系统]§a直播间授权通过,感谢您选择我们的产品.");
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
}
}
}
}
} }

View File

@ -0,0 +1,15 @@
package com.io.yutian.mclive.listener;
import com.io.yutian.livemutually.liveroom.User;
import com.io.yutian.mclive.event.LiveGiftEvents;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class RankListener implements Listener {
@EventHandler
public void onLiveGift(LiveGiftEvents event) {
User user =event.getUser();
}
}

View File

@ -20,51 +20,6 @@ import java.util.List;
public class SoundsMenu implements Listener { public class SoundsMenu implements Listener {
public static String invTitle = "我的世界整蛊 - 声音列表"; public static String invTitle = "我的世界整蛊 - 声音列表";
@EventHandler
public void onClick(InventoryClickEvent e){
int rawSlot = e.getRawSlot();
Inventory inv = e.getInventory();
Player p = (Player) e.getWhoClicked();
ItemStack item = e.getCurrentItem();
if(e.getView().getTitle().equalsIgnoreCase(invTitle)){
e.setCancelled(true);
int Pages = e.getInventory().getItem(45).getAmount();
if(e.getRawSlot() == 45){
p.playSound(p.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,2);
if(Pages >= 2 && Pages <= 31){
SoundsMenu.OpenGui(p,Pages - 1);
} else {
p.sendMessage("§c[消息]§a已经是第一页了!");
}
}
if(e.getRawSlot() == 53){
p.playSound(p.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,2);
if(Pages >= 1 && Pages <= 32){
SoundsMenu.OpenGui(p,Pages + 1);
} else {
p.sendMessage("§c[消息]§a已经是最后一页了!");
}
}
if(rawSlot >= 0 && rawSlot < 45){
if(item != null && item.getType() != Material.AIR) {
NBTItem nbt = new NBTItem(item);
if (nbt.hasKey("sound")) {
String sound = nbt.getString("sound");
p.playSound(p.getLocation(), sound, 1.0F, 1.0F);
p.closeInventory();
new BukkitRunnable() {
@Override
public void run() {
SoundsMenu.OpenGui(p, Pages);
}
}.runTaskLater(Main.plugin, 15L);
}
}
}
}
}
public static List<String> soundList = new ArrayList<>(); public static List<String> soundList = new ArrayList<>();
public static void OpenGui(Player p, int page) { public static void OpenGui(Player p, int page) {
@ -122,4 +77,48 @@ public class SoundsMenu implements Listener {
item.setItemMeta(meta); item.setItemMeta(meta);
return item; return item;
} }
@EventHandler
public void onClick(InventoryClickEvent e) {
int rawSlot = e.getRawSlot();
Inventory inv = e.getInventory();
Player p = (Player) e.getWhoClicked();
ItemStack item = e.getCurrentItem();
if (e.getView().getTitle().equalsIgnoreCase(invTitle)) {
e.setCancelled(true);
int Pages = e.getInventory().getItem(45).getAmount();
if (e.getRawSlot() == 45) {
p.playSound(p.getLocation(), Sound.BLOCK_COMPARATOR_CLICK, 1, 2);
if (Pages >= 2 && Pages <= 31) {
SoundsMenu.OpenGui(p, Pages - 1);
} else {
p.sendMessage("§c[消息]§a已经是第一页了!");
}
}
if (e.getRawSlot() == 53) {
p.playSound(p.getLocation(), Sound.BLOCK_COMPARATOR_CLICK, 1, 2);
if (Pages >= 1 && Pages <= 32) {
SoundsMenu.OpenGui(p, Pages + 1);
} else {
p.sendMessage("§c[消息]§a已经是最后一页了!");
}
}
if (rawSlot >= 0 && rawSlot < 45) {
if (item != null && item.getType() != Material.AIR) {
NBTItem nbt = new NBTItem(item);
if (nbt.hasKey("sound")) {
String sound = nbt.getString("sound");
p.playSound(p.getLocation(), sound, 1.0F, 1.0F);
p.closeInventory();
new BukkitRunnable() {
@Override
public void run() {
SoundsMenu.OpenGui(p, Pages);
}
}.runTaskLater(Main.plugin, 15L);
}
}
}
}
}
} }

View File

@ -1,10 +1,10 @@
package com.io.yutian.mclive.live; package com.io.yutian.mclive.live;
import com.io.yutian.mclive.util.ConfigYml;
import com.io.yutian.mclive.Main; import com.io.yutian.mclive.Main;
import com.io.yutian.mclive.data.GiftManage; import com.io.yutian.livemutually.manager.GiftManager;
import com.io.yutian.mclive.event.*; import com.io.yutian.mclive.event.*;
import com.io.yutian.mclive.listener.LiveAdminGui; import com.io.yutian.mclive.listener.LiveAdminGui;
import com.io.yutian.mclive.util.ConfigYml;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -16,7 +16,10 @@ public class LiveEvent implements Listener {
private ConfigYml configYml; private ConfigYml configYml;
public LiveEvent(ConfigYml configYml){this.configYml = configYml;} public LiveEvent(ConfigYml configYml) {
this.configYml = configYml;
}
@EventHandler @EventHandler
public void onGift(LiveGiftEvents e) { public void onGift(LiveGiftEvents e) {
if (Main.check_plugin) { if (Main.check_plugin) {
@ -26,13 +29,13 @@ public class LiveEvent implements Listener {
String gift_name = e.getName(); String gift_name = e.getName();
long gift_amount = e.getAmount(); long gift_amount = e.getAmount();
if (Main.giftStatistics && ConfigYml.mysqlState) { if (Main.giftStatistics && ConfigYml.mysqlState) {
GiftManage giftManage = Main.giftManage; GiftManager giftManager = Main.giftManager;
String name = e.getPlayer().getName(); String name = e.getPlayer().getName();
int trillGift = giftManage.getGiftMoney(gift_name); int trillGift = giftManager.getGiftMoney(gift_name);
if (gift_amount >= 2) { if (gift_amount >= 2) {
giftManage.addTotalMoney(name,trillGift, gift_amount); giftManager.addTotalMoney(name, trillGift, gift_amount);
} else { } else {
giftManage.addTotalMoney(name,trillGift); giftManager.addTotalMoney(name, trillGift);
} }
} }
// Bukkit.getConsoleSender().sendMessage("[直播互动 " + e.getPlayer().getName() + "] 类型: " + type + " 用户: " + audience + " 礼物: " + gift_name + "x" + gift_amount); // Bukkit.getConsoleSender().sendMessage("[直播互动 " + e.getPlayer().getName() + "] 类型: " + type + " 用户: " + audience + " 礼物: " + gift_name + "x" + gift_amount);

View File

@ -54,7 +54,10 @@ public class ConfigYml {
Main.plugin.saveConfig(); Main.plugin.saveConfig();
} }
public boolean isMainDebug() {return MainDebug;} public boolean isMainDebug() {
return MainDebug;
}
public void setMainDebug(boolean butt) { public void setMainDebug(boolean butt) {
FileConfiguration yml = Main.plugin.getConfig(); FileConfiguration yml = Main.plugin.getConfig();
yml.set("MainDebug", butt); yml.set("MainDebug", butt);
@ -62,13 +65,17 @@ public class ConfigYml {
MainDebug = butt; MainDebug = butt;
} }
public long getGifts_delay() {return gifts_delay;} public long getGifts_delay() {
return gifts_delay;
}
public void setGifts_delay(long gifts_delay) { public void setGifts_delay(long gifts_delay) {
FileConfiguration yml = Main.plugin.getConfig(); FileConfiguration yml = Main.plugin.getConfig();
yml.set("GiftDelay", gifts_delay); yml.set("GiftDelay", gifts_delay);
Main.plugin.saveConfig(); Main.plugin.saveConfig();
this.gifts_delay = gifts_delay; this.gifts_delay = gifts_delay;
} }
public String getGameMode() { public String getGameMode() {
return this.GameMode; return this.GameMode;
} }
@ -83,6 +90,7 @@ public class ConfigYml {
public HashMap<String, String> getRoomId_Map() { public HashMap<String, String> getRoomId_Map() {
return this.RoomId_Map; return this.RoomId_Map;
} }
public void setRoomId(String playName, String roomId) { public void setRoomId(String playName, String roomId) {
this.RoomId_Map.put(playName, roomId); this.RoomId_Map.put(playName, roomId);
} }

View File

@ -0,0 +1,34 @@
package com.io.yutian.mclive.util;
import java.io.*;
import java.net.URL;
import java.util.Base64;
public class FileUtil {
public static void downloadImage(String imageUrl, File destinationFile, Runnable callback) {
try (InputStream inputStream = new URL(imageUrl).openStream();
OutputStream outputStream = new FileOutputStream(destinationFile)) {
byte[] buffer = new byte[2048];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
callback.run();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String convertImageToBase64(File imageFile) {
try (FileInputStream fileInputStream = new FileInputStream(imageFile)) {
byte[] imageBytes = new byte[(int) imageFile.length()];
fileInputStream.read(imageBytes);
return Base64.getEncoder().encodeToString(imageBytes);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -1,13 +1,21 @@
package com.io.yutian.mclive.util; package com.io.yutian.mclive.util;
import cn.hamster3.cdapi.CDTimeAPI; import cn.hamster3.cdapi.CDTimeAPI;
import com.io.yutian.livemutually.manager.GiftData; import com.io.yutian.livemutually.manager.GiftManager;
import com.io.yutian.livemutually.manager.UserData; import com.io.yutian.livemutually.manager.RankManager;
import com.io.yutian.livemutually.wss.*; import com.io.yutian.livemutually.manager.UserManager;
import com.io.yutian.mclive.data.GiftData;
import com.io.yutian.mclive.data.UserData;
import com.io.yutian.livemutually.wss.KSAPILiveRoomWatcher;
import com.io.yutian.livemutually.wss.KuaiShouChat;
import com.io.yutian.livemutually.wss.KuaiShouLike;
import com.io.yutian.livemutually.wss.KuaiShouUser;
import com.io.yutian.mclive.Main; import com.io.yutian.mclive.Main;
import com.io.yutian.mclive.data.UserResourceData;
import com.io.yutian.mclive.event.LiveGiftEvents; import com.io.yutian.mclive.event.LiveGiftEvents;
import com.io.yutian.mclive.event.ZhuboAPI; import com.io.yutian.mclive.event.ZhuboAPI;
import com.io.yutian.verify.AESUtil; import com.io.yutian.verify.AESUtil;
import json.JSONArray;
import json.JSONObject; import json.JSONObject;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -19,8 +27,14 @@ import java.util.HashMap;
public class MessageUtil { public class MessageUtil {
// H8dyaR95ZJwZ6PikZ1qmoIY1 密匙
private static final String AES_KEY = "01001000001110000110010001111001011000010101001000111001001101010101101001001010011101110101101000110110010100000110100101101"; // 与Python中相同的密钥
public static HashMap<String, UserData> userDataMap = new HashMap<>();
public static void parse(Player player, String py_data) { public static void parse(Player player, String py_data) {
if(py_data.isEmpty()){return;} if (py_data.isEmpty()) {
return;
}
if (ZhuboAPI.getRoomLiveName().equalsIgnoreCase("KuaiShou")) { if (ZhuboAPI.getRoomLiveName().equalsIgnoreCase("KuaiShou")) {
JSONObject jsonObject = new JSONObject(py_data); JSONObject jsonObject = new JSONObject(py_data);
if (py_data.contains("type")) { if (py_data.contains("type")) {
@ -48,6 +62,7 @@ public class MessageUtil {
String message = "§6[日志 - 礼物触发] §f" + player.getName() + " >>> " + nickName + " = §a" + giftName + " 数量: " + count_color + newCount; String message = "§6[日志 - 礼物触发] §f" + player.getName() + " >>> " + nickName + " = §a" + giftName + " 数量: " + count_color + newCount;
Bukkit.getConsoleSender().sendMessage(message); Bukkit.getConsoleSender().sendMessage(message);
LiveGiftEvents event = new LiveGiftEvents(player, new KuaiShouUser(nickName), giftName, newCount); LiveGiftEvents event = new LiveGiftEvents(player, new KuaiShouUser(nickName), giftName, newCount);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
} }
} else if (type.equalsIgnoreCase("发言")) { } else if (type.equalsIgnoreCase("发言")) {
@ -82,7 +97,10 @@ public class MessageUtil {
return; return;
} }
JSONObject dataObject = new JSONObject(jsonObject.getString("data")); JSONObject dataObject = new JSONObject(jsonObject.getString("data"));
String nickName = dataObject.getJSONObject("user").getString("nickName"); JSONObject userJSONObject = dataObject.getJSONObject("user");
String nickName = userJSONObject.getString("nickName");
UserResourceData userResourceData = parseUserResourceData(userJSONObject);
UserManager.setUserResourceData(nickName, userResourceData);
// 礼物名 // 礼物名
String giftName = dataObject.getJSONObject("gift").getString("name"); String giftName = dataObject.getJSONObject("gift").getString("name");
// 礼物数量 // 礼物数量
@ -138,6 +156,7 @@ public class MessageUtil {
Bukkit.getConsoleSender().sendMessage(message); Bukkit.getConsoleSender().sendMessage(message);
LiveGiftEvents event = new LiveGiftEvents(player, new KuaiShouUser(nickName), giftName, newCount); LiveGiftEvents event = new LiveGiftEvents(player, new KuaiShouUser(nickName), giftName, newCount);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
RankManager.addUserAmount(nickName, Main.giftManager.getGiftMoney(giftName) * newCount);
} }
} else if (type.equalsIgnoreCase("chat_message")) { } else if (type.equalsIgnoreCase("chat_message")) {
if (!ZhuboAPI.isWsRoomIdSame(player)) { if (!ZhuboAPI.isWsRoomIdSame(player)) {
@ -192,9 +211,6 @@ public class MessageUtil {
public static void sendConsoleMessage(String message) { public static void sendConsoleMessage(String message) {
// Bukkit.getConsoleSender().sendMessage("§6[弹幕监听] " + message); // Bukkit.getConsoleSender().sendMessage("§6[弹幕监听] " + message);
} }
public static HashMap<String, UserData> userDataMap = new HashMap<>();
// H8dyaR95ZJwZ6PikZ1qmoIY1 密匙
private static final String AES_KEY = "01001000001110000110010001111001011000010101001000111001001101010101101001001010011101110101101000110110010100000110100101101"; // 与Python中相同的密钥
public static String decrypt_ecb(String encryptedMessage) throws Exception { public static String decrypt_ecb(String encryptedMessage) throws Exception {
// Base64解码 // Base64解码
@ -209,4 +225,21 @@ public class MessageUtil {
// 转换为字符串 // 转换为字符串
return new String(decryptedBytes, "UTF-8"); return new String(decryptedBytes, "UTF-8");
} }
private static UserResourceData parseUserResourceData(JSONObject jsonObject) {
String nickname = jsonObject.getString("nickName");
String avatarThumb = jsonObject.getJSONObject("AvatarThumb").getJSONArray("urlListList").getString(0);
int level = 1;
if (jsonObject.has("BadgeImageList")) {
JSONArray jsonArray = jsonObject.getJSONArray("BadgeImageList");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
String url = jsonObject1.getString("uri");
if (url.startsWith("webcast/new_user_grade_level")) {
level = jsonObject1.getJSONObject("content").getInt("level");
}
}
}
return new UserResourceData(nickname, avatarThumb, level);
}
} }

View File

@ -14,9 +14,9 @@ import java.util.Base64;
public class AESUtil { public class AESUtil {
private static final String KEY_ALGORITHM = "AES";
// AES/ECB/PKCS5Padding // AES/ECB/PKCS5Padding
public static final String DEFAULT_CIPHER_ALGORITHM = "101101000011010100110011010101010000011000010110010001100100011010010110111001100111"; public static final String DEFAULT_CIPHER_ALGORITHM = "101101000011010100110011010101010000011000010110010001100100011010010110111001100111";
private static final String KEY_ALGORITHM = "AES";
// 将二进制字符串转换为普通字符串 // 将二进制字符串转换为普通字符串
public static String convertString(String binaryString) { public static String convertString(String binaryString) {
@ -43,12 +43,10 @@ public class AESUtil {
if (verifyResult == PluginVerifyResult.USER_STATE_DISABLE) { if (verifyResult == PluginVerifyResult.USER_STATE_DISABLE) {
Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的直播间授权已到期."); Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的直播间授权已到期.");
p.sendMessage("§c[系统]§a验证尚未通过,您的直播间授权已到期."); p.sendMessage("§c[系统]§a验证尚未通过,您的直播间授权已到期.");
} else } else if (verifyResult == PluginVerifyResult.FAIL_CODE) {
if(verifyResult == PluginVerifyResult.FAIL_CODE){
Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的直播间尚未进行授权. " + roomId); Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的直播间尚未进行授权. " + roomId);
p.sendMessage("§c[系统]§a验证尚未通过,直播间§e<" + roomId + ">§a尚未进行授权."); p.sendMessage("§c[系统]§a验证尚未通过,直播间§e<" + roomId + ">§a尚未进行授权.");
} else } else if (verifyResult == PluginVerifyResult.FAIL_TIMEOUT) {
if(verifyResult == PluginVerifyResult.FAIL_TIMEOUT){
Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的本地网络有问题,无法连接验证服务器."); Bukkit.getConsoleSender().sendMessage("[验证日志 - 拦截] " + p.getName() + " 的本地网络有问题,无法连接验证服务器.");
p.sendMessage("§c[系统]§a验证尚未通过,您当前的网络环境有问题."); p.sendMessage("§c[系统]§a验证尚未通过,您当前的网络环境有问题.");
} else { } else {

View File

@ -4,7 +4,6 @@ import json.JSONObject;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
@ -41,6 +40,7 @@ public class VerifyHandler {
return PluginVerifyResult.UNKNOWN; return PluginVerifyResult.UNKNOWN;
} }
} }
public static String getServerIp() { public static String getServerIp() {
String a = "47."; String a = "47.";
String b = "111."; String b = "111.";
@ -50,6 +50,7 @@ public class VerifyHandler {
String f = "81"; String f = "81";
return a + b + c + d + ":" + e + f; return a + b + c + d + ":" + e + f;
} }
private static String get(String plugin, String code) throws Exception { private static String get(String plugin, String code) throws Exception {
String url = "/verify?plugin=" + plugin + "&code=" + code; String url = "/verify?plugin=" + plugin + "&code=" + code;
URL realUrl = new URL("http://" + getServerIp() + url); URL realUrl = new URL("http://" + getServerIp() + url);

View File

@ -94,10 +94,8 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Construct a JSONArray from a JSONTokener. * Construct a JSONArray from a JSONTokener.
* *
* @param x * @param x A JSONTokener
* A JSONTokener * @throws JSONException If there is a syntax error.
* @throws JSONException
* If there is a syntax error.
*/ */
public JSONArray(JSONTokener x) throws JSONException { public JSONArray(JSONTokener x) throws JSONException {
this(); this();
@ -147,12 +145,10 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Construct a JSONArray from a source JSON text. * Construct a JSONArray from a source JSON text.
* *
* @param source * @param source A string that begins with <code>[</code>&nbsp;<small>(left
* A string that begins with <code>[</code>&nbsp;<small>(left
* bracket)</small> and ends with <code>]</code> * bracket)</small> and ends with <code>]</code>
* &nbsp;<small>(right bracket)</small>. * &nbsp;<small>(right bracket)</small>.
* @throws JSONException * @throws JSONException If there is a syntax error.
* If there is a syntax error.
*/ */
public JSONArray(String source) throws JSONException { public JSONArray(String source) throws JSONException {
this(new JSONTokener(source)); this(new JSONTokener(source));
@ -161,8 +157,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Construct a JSONArray from a Collection. * Construct a JSONArray from a Collection.
* *
* @param collection * @param collection A Collection.
* A Collection.
*/ */
public JSONArray(Collection<?> collection) { public JSONArray(Collection<?> collection) {
if (collection == null) { if (collection == null) {
@ -178,14 +173,10 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Construct a JSONArray from an array. * Construct a JSONArray from an array.
* *
* @param array * @param array Array. If the parameter passed is null, or not an array, an
* Array. If the parameter passed is null, or not an array, an
* exception will be thrown. * exception will be thrown.
* * @throws JSONException If not an array or if an array value is non-finite number.
* @throws JSONException * @throws NullPointerException Thrown if the array parameter is null.
* If not an array or if an array value is non-finite number.
* @throws NullPointerException
* Thrown if the array parameter is null.
*/ */
public JSONArray(Object array) throws JSONException { public JSONArray(Object array) throws JSONException {
this(); this();
@ -201,6 +192,41 @@ public class JSONArray implements Iterable<Object> {
} }
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
*
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + "."
, cause);
}
/**
* Create a new JSONException in a common format for incorrect conversions.
*
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Object value,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")."
, cause);
}
@Override @Override
public Iterator<Object> iterator() { public Iterator<Object> iterator() {
return this.myArrayList.iterator(); return this.myArrayList.iterator();
@ -209,11 +235,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the object value associated with an index. * Get the object value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return An object value. * @return An object value.
* @throws JSONException * @throws JSONException If there is no value for the index.
* If there is no value for the index.
*/ */
public Object get(int index) throws JSONException { public Object get(int index) throws JSONException {
Object object = this.opt(index); Object object = this.opt(index);
@ -227,11 +251,9 @@ public class JSONArray implements Iterable<Object> {
* Get the boolean value associated with an index. The string values "true" * Get the boolean value associated with an index. The string values "true"
* and "false" are converted to boolean. * and "false" are converted to boolean.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The truth. * @return The truth.
* @throws JSONException * @throws JSONException If there is no value for the index or if the value is not
* If there is no value for the index or if the value is not
* convertible to boolean. * convertible to boolean.
*/ */
public boolean getBoolean(int index) throws JSONException { public boolean getBoolean(int index) throws JSONException {
@ -251,11 +273,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the double value associated with an index. * Get the double value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
* @throws JSONException * @throws JSONException If the key is not found or if the value cannot be converted
* If the key is not found or if the value cannot be converted
* to a number. * to a number.
*/ */
public double getDouble(int index) throws JSONException { public double getDouble(int index) throws JSONException {
@ -273,11 +293,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the float value associated with a key. * Get the float value associated with a key.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The numeric value. * @return The numeric value.
* @throws JSONException * @throws JSONException if the key is not found or if the value is not a Number
* if the key is not found or if the value is not a Number
* object and cannot be converted to a number. * object and cannot be converted to a number.
*/ */
public float getFloat(int index) throws JSONException { public float getFloat(int index) throws JSONException {
@ -295,11 +313,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the Number value associated with a key. * Get the Number value associated with a key.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The numeric value. * @return The numeric value.
* @throws JSONException * @throws JSONException if the key is not found or if the value is not a Number
* if the key is not found or if the value is not a Number
* object and cannot be converted to a number. * object and cannot be converted to a number.
*/ */
public Number getNumber(int index) throws JSONException { public Number getNumber(int index) throws JSONException {
@ -317,15 +333,11 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the enum value associated with an index. * Get the enum value associated with an index.
* *
* @param <E> * @param <E> Enum Type
* Enum Type * @param clazz The type of enum to retrieve.
* @param clazz * @param index The index must be between 0 and length() - 1.
* The type of enum to retrieve.
* @param index
* The index must be between 0 and length() - 1.
* @return The enum value at the index location * @return The enum value at the index location
* @throws JSONException * @throws JSONException if the key is not found or if the value cannot be converted
* if the key is not found or if the value cannot be converted
* to an enum. * to an enum.
*/ */
public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONException { public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONException {
@ -346,11 +358,9 @@ public class JSONArray implements Iterable<Object> {
* will be used. See notes on the constructor for conversion issues that * will be used. See notes on the constructor for conversion issues that
* may arise. * may arise.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
* @throws JSONException * @throws JSONException If the key is not found or if the value cannot be converted
* If the key is not found or if the value cannot be converted
* to a BigDecimal. * to a BigDecimal.
*/ */
public BigDecimal getBigDecimal(int index) throws JSONException { public BigDecimal getBigDecimal(int index) throws JSONException {
@ -365,11 +375,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the BigInteger value associated with an index. * Get the BigInteger value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
* @throws JSONException * @throws JSONException If the key is not found or if the value cannot be converted
* If the key is not found or if the value cannot be converted
* to a BigInteger. * to a BigInteger.
*/ */
public BigInteger getBigInteger(int index) throws JSONException { public BigInteger getBigInteger(int index) throws JSONException {
@ -384,11 +392,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the int value associated with an index. * Get the int value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
* @throws JSONException * @throws JSONException If the key is not found or if the value is not a number.
* If the key is not found or if the value is not a number.
*/ */
public int getInt(int index) throws JSONException { public int getInt(int index) throws JSONException {
final Object object = this.get(index); final Object object = this.get(index);
@ -405,11 +411,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the JSONArray associated with an index. * Get the JSONArray associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return A JSONArray value. * @return A JSONArray value.
* @throws JSONException * @throws JSONException If there is no value for the index. or if the value is not a
* If there is no value for the index. or if the value is not a
* JSONArray * JSONArray
*/ */
public JSONArray getJSONArray(int index) throws JSONException { public JSONArray getJSONArray(int index) throws JSONException {
@ -423,11 +427,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the JSONObject associated with an index. * Get the JSONObject associated with an index.
* *
* @param index * @param index subscript
* subscript
* @return A JSONObject value. * @return A JSONObject value.
* @throws JSONException * @throws JSONException If there is no value for the index or if the value is not a
* If there is no value for the index or if the value is not a
* JSONObject * JSONObject
*/ */
public JSONObject getJSONObject(int index) throws JSONException { public JSONObject getJSONObject(int index) throws JSONException {
@ -441,11 +443,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the long value associated with an index. * Get the long value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
* @throws JSONException * @throws JSONException If the key is not found or if the value cannot be converted
* If the key is not found or if the value cannot be converted
* to a number. * to a number.
*/ */
public long getLong(int index) throws JSONException { public long getLong(int index) throws JSONException {
@ -463,11 +463,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the string associated with an index. * Get the string associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return A string value. * @return A string value.
* @throws JSONException * @throws JSONException If there is no string value for the index.
* If there is no string value for the index.
*/ */
public String getString(int index) throws JSONException { public String getString(int index) throws JSONException {
Object object = this.get(index); Object object = this.get(index);
@ -480,8 +478,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Determine if the value is <code>null</code>. * Determine if the value is <code>null</code>.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return true if the value at the index is <code>null</code>, or if there is no value. * @return true if the value at the index is <code>null</code>, or if there is no value.
*/ */
public boolean isNull(int index) { public boolean isNull(int index) {
@ -493,11 +490,9 @@ public class JSONArray implements Iterable<Object> {
* <code>separator</code> string is inserted between each element. Warning: * <code>separator</code> string is inserted between each element. Warning:
* This method assumes that the data structure is acyclical. * This method assumes that the data structure is acyclical.
* *
* @param separator * @param separator A string that will be inserted between the elements.
* A string that will be inserted between the elements.
* @return a string. * @return a string.
* @throws JSONException * @throws JSONException If the array contains an invalid number.
* If the array contains an invalid number.
*/ */
public String join(String separator) throws JSONException { public String join(String separator) throws JSONException {
int len = this.length(); int len = this.length();
@ -527,8 +522,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the optional object value associated with an index. * Get the optional object value associated with an index.
* *
* @param index * @param index The index must be between 0 and length() - 1. If not, null is returned.
* The index must be between 0 and length() - 1. If not, null is returned.
* @return An object value, or null if there is no object at that index. * @return An object value, or null if there is no object at that index.
*/ */
public Object opt(int index) { public Object opt(int index) {
@ -541,8 +535,7 @@ public class JSONArray implements Iterable<Object> {
* if there is no value at that index, or if the value is not Boolean.TRUE * if there is no value at that index, or if the value is not Boolean.TRUE
* or the String "true". * or the String "true".
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The truth. * @return The truth.
*/ */
public boolean optBoolean(int index) { public boolean optBoolean(int index) {
@ -554,10 +547,8 @@ public class JSONArray implements Iterable<Object> {
* defaultValue if there is no value at that index or if it is not a Boolean * defaultValue if there is no value at that index or if it is not a Boolean
* or the String "true" or "false" (case insensitive). * or the String "true" or "false" (case insensitive).
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue A boolean default.
* @param defaultValue
* A boolean default.
* @return The truth. * @return The truth.
*/ */
public boolean optBoolean(int index, boolean defaultValue) { public boolean optBoolean(int index, boolean defaultValue) {
@ -573,8 +564,7 @@ public class JSONArray implements Iterable<Object> {
* if there is no value for the index, or if the value is not a number and * if there is no value for the index, or if the value is not a number and
* cannot be converted to a number. * cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
*/ */
public double optDouble(int index) { public double optDouble(int index) {
@ -586,10 +576,8 @@ public class JSONArray implements Iterable<Object> {
* is returned if there is no value for the index, or if the value is not a * is returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number. * number and cannot be converted to a number.
* *
* @param index * @param index subscript
* subscript * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public double optDouble(int index, double defaultValue) { public double optDouble(int index, double defaultValue) {
@ -609,8 +597,7 @@ public class JSONArray implements Iterable<Object> {
* if there is no value for the index, or if the value is not a number and * if there is no value for the index, or if the value is not a number and
* cannot be converted to a number. * cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
*/ */
public float optFloat(int index) { public float optFloat(int index) {
@ -622,10 +609,8 @@ public class JSONArray implements Iterable<Object> {
* is returned if there is no value for the index, or if the value is not a * is returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number. * number and cannot be converted to a number.
* *
* @param index * @param index subscript
* subscript * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public float optFloat(int index, float defaultValue) { public float optFloat(int index, float defaultValue) {
@ -645,8 +630,7 @@ public class JSONArray implements Iterable<Object> {
* there is no value for the index, or if the value is not a number and * there is no value for the index, or if the value is not a number and
* cannot be converted to a number. * cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
*/ */
public int optInt(int index) { public int optInt(int index) {
@ -658,10 +642,8 @@ public class JSONArray implements Iterable<Object> {
* returned if there is no value for the index, or if the value is not a * returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number. * number and cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public int optInt(int index, int defaultValue) { public int optInt(int index, int defaultValue) {
@ -675,12 +657,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the enum value associated with a key. * Get the enum value associated with a key.
* *
* @param <E> * @param <E> Enum Type
* Enum Type * @param clazz The type of enum to retrieve.
* @param clazz * @param index The index must be between 0 and length() - 1.
* The type of enum to retrieve.
* @param index
* The index must be between 0 and length() - 1.
* @return The enum value at the index location or null if not found * @return The enum value at the index location or null if not found
*/ */
public <E extends Enum<E>> E optEnum(Class<E> clazz, int index) { public <E extends Enum<E>> E optEnum(Class<E> clazz, int index) {
@ -690,14 +669,10 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the enum value associated with a key. * Get the enum value associated with a key.
* *
* @param <E> * @param <E> Enum Type
* Enum Type * @param clazz The type of enum to retrieve.
* @param clazz * @param index The index must be between 0 and length() - 1.
* The type of enum to retrieve. * @param defaultValue The default in case the value is not found
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default in case the value is not found
* @return The enum value at the index location or defaultValue if * @return The enum value at the index location or defaultValue if
* the value is not found or cannot be assigned to clazz * the value is not found or cannot be assigned to clazz
*/ */
@ -726,10 +701,8 @@ public class JSONArray implements Iterable<Object> {
* defaultValue is returned if there is no value for the index, or if the * defaultValue is returned if there is no value for the index, or if the
* value is not a number and cannot be converted to a number. * value is not a number and cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public BigInteger optBigInteger(int index, BigInteger defaultValue) { public BigInteger optBigInteger(int index, BigInteger defaultValue) {
@ -745,10 +718,8 @@ public class JSONArray implements Iterable<Object> {
* constructor will be used. See notes on the constructor for conversion * constructor will be used. See notes on the constructor for conversion
* issues that may arise. * issues that may arise.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) { public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
@ -759,8 +730,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Get the optional JSONArray associated with an index. * Get the optional JSONArray associated with an index.
* *
* @param index * @param index subscript
* subscript
* @return A JSONArray value, or null if the index has no value, or if the * @return A JSONArray value, or null if the index has no value, or if the
* value is not a JSONArray. * value is not a JSONArray.
*/ */
@ -774,8 +744,7 @@ public class JSONArray implements Iterable<Object> {
* the key is not found, or null if the index has no value, or if the value * the key is not found, or null if the index has no value, or if the value
* is not a JSONObject. * is not a JSONObject.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return A JSONObject value. * @return A JSONObject value.
*/ */
public JSONObject optJSONObject(int index) { public JSONObject optJSONObject(int index) {
@ -788,8 +757,7 @@ public class JSONArray implements Iterable<Object> {
* there is no value for the index, or if the value is not a number and * there is no value for the index, or if the value is not a number and
* cannot be converted to a number. * cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return The value. * @return The value.
*/ */
public long optLong(int index) { public long optLong(int index) {
@ -801,10 +769,8 @@ public class JSONArray implements Iterable<Object> {
* returned if there is no value for the index, or if the value is not a * returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number. * number and cannot be converted to a number.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return The value. * @return The value.
*/ */
public long optLong(int index, long defaultValue) { public long optLong(int index, long defaultValue) {
@ -821,8 +787,7 @@ public class JSONArray implements Iterable<Object> {
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
* would be used in cases where type coercion of the number value is unwanted. * would be used in cases where type coercion of the number value is unwanted.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return An object which is the value. * @return An object which is the value.
*/ */
public Number optNumber(int index) { public Number optNumber(int index) {
@ -835,10 +800,8 @@ public class JSONArray implements Iterable<Object> {
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
* would be used in cases where type coercion of the number value is unwanted. * would be used in cases where type coercion of the number value is unwanted.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default.
* @param defaultValue
* The default.
* @return An object which is the value. * @return An object which is the value.
*/ */
public Number optNumber(int index, Number defaultValue) { public Number optNumber(int index, Number defaultValue) {
@ -865,8 +828,7 @@ public class JSONArray implements Iterable<Object> {
* empty string if there is no value at that index. If the value is not a * empty string if there is no value at that index. If the value is not a
* string and is not null, then it is converted to a string. * string and is not null, then it is converted to a string.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1.
* @return A String value. * @return A String value.
*/ */
public String optString(int index) { public String optString(int index) {
@ -877,10 +839,8 @@ public class JSONArray implements Iterable<Object> {
* Get the optional string associated with an index. The defaultValue is * Get the optional string associated with an index. The defaultValue is
* returned if the key is not found. * returned if the key is not found.
* *
* @param index * @param index The index must be between 0 and length() - 1.
* The index must be between 0 and length() - 1. * @param defaultValue The default value.
* @param defaultValue
* The default value.
* @return A String value. * @return A String value.
*/ */
public String optString(int index, String defaultValue) { public String optString(int index, String defaultValue) {
@ -892,8 +852,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append a boolean value. This increases the array's length by one. * Append a boolean value. This increases the array's length by one.
* *
* @param value * @param value A boolean value.
* A boolean value.
* @return this. * @return this.
*/ */
public JSONArray put(boolean value) { public JSONArray put(boolean value) {
@ -904,11 +863,9 @@ public class JSONArray implements Iterable<Object> {
* Put a value in the JSONArray, where the value will be a JSONArray which * Put a value in the JSONArray, where the value will be a JSONArray which
* is produced from a Collection. * is produced from a Collection.
* *
* @param value * @param value A Collection value.
* A Collection value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the value is non-finite number.
* If the value is non-finite number.
*/ */
public JSONArray put(Collection<?> value) { public JSONArray put(Collection<?> value) {
return this.put(new JSONArray(value)); return this.put(new JSONArray(value));
@ -917,11 +874,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append a double value. This increases the array's length by one. * Append a double value. This increases the array's length by one.
* *
* @param value * @param value A double value.
* A double value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException if the value is not finite.
* if the value is not finite.
*/ */
public JSONArray put(double value) throws JSONException { public JSONArray put(double value) throws JSONException {
return this.put(Double.valueOf(value)); return this.put(Double.valueOf(value));
@ -930,11 +885,9 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append a float value. This increases the array's length by one. * Append a float value. This increases the array's length by one.
* *
* @param value * @param value A float value.
* A float value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException if the value is not finite.
* if the value is not finite.
*/ */
public JSONArray put(float value) throws JSONException { public JSONArray put(float value) throws JSONException {
return this.put(Float.valueOf(value)); return this.put(Float.valueOf(value));
@ -943,8 +896,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append an int value. This increases the array's length by one. * Append an int value. This increases the array's length by one.
* *
* @param value * @param value An int value.
* An int value.
* @return this. * @return this.
*/ */
public JSONArray put(int value) { public JSONArray put(int value) {
@ -954,8 +906,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append an long value. This increases the array's length by one. * Append an long value. This increases the array's length by one.
* *
* @param value * @param value A long value.
* A long value.
* @return this. * @return this.
*/ */
public JSONArray put(long value) { public JSONArray put(long value) {
@ -966,13 +917,10 @@ public class JSONArray implements Iterable<Object> {
* Put a value in the JSONArray, where the value will be a JSONObject which * Put a value in the JSONArray, where the value will be a JSONObject which
* is produced from a Map. * is produced from a Map.
* *
* @param value * @param value A Map value.
* A Map value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If a value in the map is non-finite number.
* If a value in the map is non-finite number. * @throws NullPointerException If a key in the map is <code>null</code>
* @throws NullPointerException
* If a key in the map is <code>null</code>
*/ */
public JSONArray put(Map<?, ?> value) { public JSONArray put(Map<?, ?> value) {
return this.put(new JSONObject(value)); return this.put(new JSONObject(value));
@ -981,13 +929,11 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Append an object value. This increases the array's length by one. * Append an object value. This increases the array's length by one.
* *
* @param value * @param value An object value. The value should be a Boolean, Double,
* An object value. The value should be a Boolean, Double,
* Integer, JSONArray, JSONObject, Long, or String, or the * Integer, JSONArray, JSONObject, Long, or String, or the
* JSONObject.NULL object. * JSONObject.NULL object.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the value is non-finite number.
* If the value is non-finite number.
*/ */
public JSONArray put(Object value) { public JSONArray put(Object value) {
JSONObject.testValidity(value); JSONObject.testValidity(value);
@ -1000,13 +946,10 @@ public class JSONArray implements Iterable<Object> {
* than the length of the JSONArray, then null elements will be added as * than the length of the JSONArray, then null elements will be added as
* necessary to pad it out. * necessary to pad it out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value A boolean value.
* @param value
* A boolean value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative.
* If the index is negative.
*/ */
public JSONArray put(int index, boolean value) throws JSONException { public JSONArray put(int index, boolean value) throws JSONException {
return this.put(index, value ? Boolean.TRUE : Boolean.FALSE); return this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
@ -1016,13 +959,10 @@ public class JSONArray implements Iterable<Object> {
* Put a value in the JSONArray, where the value will be a JSONArray which * Put a value in the JSONArray, where the value will be a JSONArray which
* is produced from a Collection. * is produced from a Collection.
* *
* @param index * @param index The subscript.
* The subscript. * @param value A Collection value.
* @param value
* A Collection value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative or if the value is non-finite.
* If the index is negative or if the value is non-finite.
*/ */
public JSONArray put(int index, Collection<?> value) throws JSONException { public JSONArray put(int index, Collection<?> value) throws JSONException {
return this.put(index, new JSONArray(value)); return this.put(index, new JSONArray(value));
@ -1033,13 +973,10 @@ public class JSONArray implements Iterable<Object> {
* the JSONArray, then null elements will be added as necessary to pad it * the JSONArray, then null elements will be added as necessary to pad it
* out. * out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value A double value.
* @param value
* A double value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative or if the value is non-finite.
* If the index is negative or if the value is non-finite.
*/ */
public JSONArray put(int index, double value) throws JSONException { public JSONArray put(int index, double value) throws JSONException {
return this.put(index, Double.valueOf(value)); return this.put(index, Double.valueOf(value));
@ -1050,13 +987,10 @@ public class JSONArray implements Iterable<Object> {
* the JSONArray, then null elements will be added as necessary to pad it * the JSONArray, then null elements will be added as necessary to pad it
* out. * out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value A float value.
* @param value
* A float value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative or if the value is non-finite.
* If the index is negative or if the value is non-finite.
*/ */
public JSONArray put(int index, float value) throws JSONException { public JSONArray put(int index, float value) throws JSONException {
return this.put(index, Float.valueOf(value)); return this.put(index, Float.valueOf(value));
@ -1067,13 +1001,10 @@ public class JSONArray implements Iterable<Object> {
* the JSONArray, then null elements will be added as necessary to pad it * the JSONArray, then null elements will be added as necessary to pad it
* out. * out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value An int value.
* @param value
* An int value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative.
* If the index is negative.
*/ */
public JSONArray put(int index, int value) throws JSONException { public JSONArray put(int index, int value) throws JSONException {
return this.put(index, Integer.valueOf(value)); return this.put(index, Integer.valueOf(value));
@ -1084,13 +1015,10 @@ public class JSONArray implements Iterable<Object> {
* the JSONArray, then null elements will be added as necessary to pad it * the JSONArray, then null elements will be added as necessary to pad it
* out. * out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value A long value.
* @param value
* A long value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative.
* If the index is negative.
*/ */
public JSONArray put(int index, long value) throws JSONException { public JSONArray put(int index, long value) throws JSONException {
return this.put(index, Long.valueOf(value)); return this.put(index, Long.valueOf(value));
@ -1100,16 +1028,12 @@ public class JSONArray implements Iterable<Object> {
* Put a value in the JSONArray, where the value will be a JSONObject that * Put a value in the JSONArray, where the value will be a JSONObject that
* is produced from a Map. * is produced from a Map.
* *
* @param index * @param index The subscript.
* The subscript. * @param value The Map value.
* @param value
* The Map value.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative or if the the value is an invalid
* If the index is negative or if the the value is an invalid
* number. * number.
* @throws NullPointerException * @throws NullPointerException If a key in the map is <code>null</code>
* If a key in the map is <code>null</code>
*/ */
public JSONArray put(int index, Map<?, ?> value) throws JSONException { public JSONArray put(int index, Map<?, ?> value) throws JSONException {
this.put(index, new JSONObject(value)); this.put(index, new JSONObject(value));
@ -1121,15 +1045,12 @@ public class JSONArray implements Iterable<Object> {
* than the length of the JSONArray, then null elements will be added as * than the length of the JSONArray, then null elements will be added as
* necessary to pad it out. * necessary to pad it out.
* *
* @param index * @param index The subscript.
* The subscript. * @param value The value to put into the array. The value should be a
* @param value
* The value to put into the array. The value should be a
* Boolean, Double, Integer, JSONArray, JSONObject, Long, or * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
* String, or the JSONObject.NULL object. * String, or the JSONObject.NULL object.
* @return this. * @return this.
* @throws JSONException * @throws JSONException If the index is negative or if the the value is an invalid
* If the index is negative or if the the value is an invalid
* number. * number.
*/ */
public JSONArray put(int index, Object value) throws JSONException { public JSONArray put(int index, Object value) throws JSONException {
@ -1232,8 +1153,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Remove an index and close the hole. * Remove an index and close the hole.
* *
* @param index * @param index The index of the element to be removed.
* The index of the element to be removed.
* @return The value that was associated with the index, or null if there * @return The value that was associated with the index, or null if there
* was no value. * was no value.
*/ */
@ -1286,13 +1206,11 @@ public class JSONArray implements Iterable<Object> {
* Produce a JSONObject by combining a JSONArray of names with the values of * Produce a JSONObject by combining a JSONArray of names with the values of
* this JSONArray. * this JSONArray.
* *
* @param names * @param names A JSONArray containing a list of key strings. These will be
* A JSONArray containing a list of key strings. These will be
* paired with the values. * paired with the values.
* @return A JSONObject, or null if there are no names or if this JSONArray * @return A JSONObject, or null if there are no names or if this JSONArray
* has no values. * has no values.
* @throws JSONException * @throws JSONException If any of the names are null.
* If any of the names are null.
*/ */
public JSONObject toJSONObject(JSONArray names) throws JSONException { public JSONObject toJSONObject(JSONArray names) throws JSONException {
if (names == null || names.isEmpty() || this.isEmpty()) { if (names == null || names.isEmpty() || this.isEmpty()) {
@ -1345,8 +1263,7 @@ public class JSONArray implements Iterable<Object> {
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* </b> * </b>
* *
* @param indentFactor * @param indentFactor The number of spaces to add to each level of indentation.
* The number of spaces to add to each level of indentation.
* @return a printable, displayable, transmittable representation of the * @return a printable, displayable, transmittable representation of the
* object, beginning with <code>[</code>&nbsp;<small>(left * object, beginning with <code>[</code>&nbsp;<small>(left
* bracket)</small> and ending with <code>]</code> * bracket)</small> and ending with <code>]</code>
@ -1393,12 +1310,9 @@ public class JSONArray implements Iterable<Object> {
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* </b> * </b>
* *
* @param writer * @param writer Writes the serialized JSON
* Writes the serialized JSON * @param indentFactor The number of spaces to add to each level of indentation.
* @param indentFactor * @param indent The indentation of the top level.
* The number of spaces to add to each level of indentation.
* @param indent
* The indentation of the top level.
* @return The writer. * @return The writer.
* @throws JSONException * @throws JSONException
*/ */
@ -1481,37 +1395,4 @@ public class JSONArray implements Iterable<Object> {
return this.myArrayList.isEmpty(); return this.myArrayList.isEmpty();
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + "."
, cause);
}
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Object value,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")."
, cause);
}
} }

View File

@ -7,14 +7,15 @@ package json;
* @version 2015-12-09 * @version 2015-12-09
*/ */
public class JSONException extends RuntimeException { public class JSONException extends RuntimeException {
/** Serialization ID */ /**
* Serialization ID
*/
private static final long serialVersionUID = 0; private static final long serialVersionUID = 0;
/** /**
* Constructs a JSONException with an explanatory message. * Constructs a JSONException with an explanatory message.
* *
* @param message * @param message Detail about the reason for the exception.
* Detail about the reason for the exception.
*/ */
public JSONException(final String message) { public JSONException(final String message) {
super(message); super(message);
@ -23,10 +24,8 @@ public class JSONException extends RuntimeException {
/** /**
* Constructs a JSONException with an explanatory message and cause. * Constructs a JSONException with an explanatory message and cause.
* *
* @param message * @param message Detail about the reason for the exception.
* Detail about the reason for the exception. * @param cause The cause.
* @param cause
* The cause.
*/ */
public JSONException(final String message, final Throwable cause) { public JSONException(final String message, final Throwable cause) {
super(message, cause); super(message, cause);
@ -35,8 +34,7 @@ public class JSONException extends RuntimeException {
/** /**
* Constructs a new JSONException with the specified cause. * Constructs a new JSONException with the specified cause.
* *
* @param cause * @param cause The cause.
* The cause.
*/ */
public JSONException(final Throwable cause) { public JSONException(final Throwable cause) {
super(cause.getMessage(), cause); super(cause.getMessage(), cause);

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ SOFTWARE.
/** /**
* A JSON Pointer is a simple query language defined for JSON documents by * A JSON Pointer is a simple query language defined for JSON documents by
* <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a>. * <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a>.
* * <p>
* In a nutshell, JSONPointer allows the user to navigate into a JSON document * In a nutshell, JSONPointer allows the user to navigate into a JSON document
* using strings, and retrieve targeted objects, like a simple form of XPATH. * using strings, and retrieve targeted objects, like a simple form of XPATH.
* Path segments are separated by the '/' char, which signifies the root of * Path segments are separated by the '/' char, which signifies the root of
@ -55,76 +55,6 @@ public class JSONPointer {
// used for URL encoding and decoding // used for URL encoding and decoding
private static final String ENCODING = "utf-8"; private static final String ENCODING = "utf-8";
/**
* This class allows the user to build a JSONPointer in steps, using
* exactly one segment in each step.
*/
public static class Builder {
// Segments for the eventual JSONPointer string
private final List<String> refTokens = new ArrayList<String>();
/**
* Creates a {@code JSONPointer} instance using the tokens previously set using the
* {@link #append(String)} method calls.
*/
public JSONPointer build() {
return new JSONPointer(this.refTokens);
}
/**
* Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
*
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
* argument of this method MUST NOT be escaped. If you want to query the property called
* {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
* need to escape it as {@code "a~0b"}.
*
* @param token the new token to be appended to the list
* @return {@code this}
* @throws NullPointerException if {@code token} is null
*/
public Builder append(String token) {
if (token == null) {
throw new NullPointerException("token cannot be null");
}
this.refTokens.add(token);
return this;
}
/**
* Adds an integer to the reference token list. Although not necessarily, mostly this token will
* denote an array index.
*
* @param arrayIndex the array index to be added to the token list
* @return {@code this}
*/
public Builder append(int arrayIndex) {
this.refTokens.add(String.valueOf(arrayIndex));
return this;
}
}
/**
* Static factory method for {@link Builder}. Example usage:
*
* <pre><code>
* JSONPointer pointer = JSONPointer.builder()
* .append("obj")
* .append("other~key").append("another/key")
* .append("\"")
* .append(0)
* .build();
* </code></pre>
*
* @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
* {@link Builder#append(String)} calls.
*/
public static Builder builder() {
return new Builder();
}
// Segments for the JSONPointer string // Segments for the JSONPointer string
private final List<String> refTokens; private final List<String> refTokens;
@ -186,12 +116,73 @@ public class JSONPointer {
this.refTokens = new ArrayList<String>(refTokens); this.refTokens = new ArrayList<String>(refTokens);
} }
/**
* Static factory method for {@link Builder}. Example usage:
*
* <pre><code>
* JSONPointer pointer = JSONPointer.builder()
* .append("obj")
* .append("other~key").append("another/key")
* .append("\"")
* .append(0)
* .build();
* </code></pre>
*
* @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
* {@link Builder#append(String)} calls.
*/
public static Builder builder() {
return new Builder();
}
private static String unescape(String token) { private static String unescape(String token) {
return token.replace("~1", "/").replace("~0", "~") return token.replace("~1", "/").replace("~0", "~")
.replace("\\\"", "\"") .replace("\\\"", "\"")
.replace("\\\\", "\\"); .replace("\\\\", "\\");
} }
/**
* Matches a JSONArray element by ordinal position
*
* @param current the JSONArray to be evaluated
* @param indexToken the array index in string form
* @return the matched object. If no matching item is found a
* @throws JSONPointerException is thrown if the index is out of bounds
*/
private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
try {
int index = Integer.parseInt(indexToken);
JSONArray currentArr = (JSONArray) current;
if (index >= currentArr.length()) {
throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken,
Integer.valueOf(currentArr.length())));
}
try {
return currentArr.get(index);
} catch (JSONException e) {
throw new JSONPointerException("Error reading value at index position " + index, e);
}
} catch (NumberFormatException e) {
throw new JSONPointerException(format("%s is not an array index", indexToken), e);
}
}
/**
* Escapes path segment values to an unambiguous form.
* The escape char to be inserted is '~'. The chars to be escaped
* are ~, which maps to ~0, and /, which maps to ~1. Backslashes
* and double quote chars are also escaped.
*
* @param token the JSONPointer segment value to be escaped
* @return the escaped value for the token
*/
private static String escape(String token) {
return token.replace("~", "~0")
.replace("/", "~1")
.replace("\\", "\\\\")
.replace("\"", "\\\"");
}
/** /**
* Evaluates this JSON Pointer on the given {@code document}. The {@code document} * Evaluates this JSON Pointer on the given {@code document}. The {@code document}
* is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty * is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty
@ -221,31 +212,6 @@ public class JSONPointer {
return current; return current;
} }
/**
* Matches a JSONArray element by ordinal position
* @param current the JSONArray to be evaluated
* @param indexToken the array index in string form
* @return the matched object. If no matching item is found a
* @throws JSONPointerException is thrown if the index is out of bounds
*/
private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
try {
int index = Integer.parseInt(indexToken);
JSONArray currentArr = (JSONArray) current;
if (index >= currentArr.length()) {
throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken,
Integer.valueOf(currentArr.length())));
}
try {
return currentArr.get(index);
} catch (JSONException e) {
throw new JSONPointerException("Error reading value at index position " + index, e);
}
} catch (NumberFormatException e) {
throw new JSONPointerException(format("%s is not an array index", indexToken), e);
}
}
/** /**
* Returns a string representing the JSONPointer path value using string * Returns a string representing the JSONPointer path value using string
* representation * representation
@ -259,21 +225,6 @@ public class JSONPointer {
return rval.toString(); return rval.toString();
} }
/**
* Escapes path segment values to an unambiguous form.
* The escape char to be inserted is '~'. The chars to be escaped
* are ~, which maps to ~0, and /, which maps to ~1. Backslashes
* and double quote chars are also escaped.
* @param token the JSONPointer segment value to be escaped
* @return the escaped value for the token
*/
private static String escape(String token) {
return token.replace("~", "~0")
.replace("/", "~1")
.replace("\\", "\\\\")
.replace("\"", "\\\"");
}
/** /**
* Returns a string representing the JSONPointer path value using URI * Returns a string representing the JSONPointer path value using URI
* fragment identifier representation * fragment identifier representation
@ -290,4 +241,54 @@ public class JSONPointer {
} }
} }
/**
* This class allows the user to build a JSONPointer in steps, using
* exactly one segment in each step.
*/
public static class Builder {
// Segments for the eventual JSONPointer string
private final List<String> refTokens = new ArrayList<String>();
/**
* Creates a {@code JSONPointer} instance using the tokens previously set using the
* {@link #append(String)} method calls.
*/
public JSONPointer build() {
return new JSONPointer(this.refTokens);
}
/**
* Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
* <p>
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
* argument of this method MUST NOT be escaped. If you want to query the property called
* {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
* need to escape it as {@code "a~0b"}.
*
* @param token the new token to be appended to the list
* @return {@code this}
* @throws NullPointerException if {@code token} is null
*/
public Builder append(String token) {
if (token == null) {
throw new NullPointerException("token cannot be null");
}
this.refTokens.add(token);
return this;
}
/**
* Adds an integer to the reference token list. Although not necessarily, mostly this token will
* denote an array index.
*
* @param arrayIndex the array index to be added to the token list
* @return {@code this}
*/
public Builder append(int arrayIndex) {
this.refTokens.add(String.valueOf(arrayIndex));
return this;
}
}
} }

View File

@ -40,4 +40,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* present at any level in the class hierarchy, then the method will * present at any level in the class hierarchy, then the method will
* not be serialized from the bean into the JSONObject. * not be serialized from the bean into the JSONObject.
*/ */
public @interface JSONPropertyIgnore { } public @interface JSONPropertyIgnore {
}

View File

@ -1,4 +1,5 @@
package json; package json;
/** /**
* The <code>JSONString</code> interface allows a <code>toJSONString()</code> * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
* method so that a class can change the behavior of * method so that a class can change the behavior of

View File

@ -53,6 +53,7 @@ import java.io.StringWriter;
* you. Objects and arrays can be nested up to 20 levels deep. * you. Objects and arrays can be nested up to 20 levels deep.
* <p> * <p>
* This can sometimes be easier than using a JSONObject to build a string. * This can sometimes be easier than using a JSONObject to build a string.
*
* @author JSON.org * @author JSON.org
* @version 2015-12-09 * @version 2015-12-09
*/ */
@ -70,6 +71,7 @@ public class JSONStringer extends JSONWriter {
* problem in the construction of the JSON text (such as the calls to * problem in the construction of the JSON text (such as the calls to
* <code>array</code> were not properly balanced with calls to * <code>array</code> were not properly balanced with calls to
* <code>endArray</code>). * <code>endArray</code>).
*
* @return The JSON text. * @return The JSON text.
*/ */
@Override @Override

View File

@ -30,25 +30,42 @@ SOFTWARE.
* A JSONTokener takes a source string and extracts characters and tokens from * A JSONTokener takes a source string and extracts characters and tokens from
* it. It is used by the JSONObject and JSONArray constructors to parse * it. It is used by the JSONObject and JSONArray constructors to parse
* JSON source strings. * JSON source strings.
*
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2014-05-03
*/ */
public class JSONTokener { public class JSONTokener {
/** current read character position on the current line. */ /**
private long character; * Reader for the input.
/** flag to indicate if the end of the input has been found. */ */
private boolean eof;
/** current read index of the input. */
private long index;
/** current line of the input. */
private long line;
/** previous character read from the input. */
private char previous;
/** Reader for the input. */
private final Reader reader; private final Reader reader;
/** flag to indicate that a previous character was requested. */ /**
* current read character position on the current line.
*/
private long character;
/**
* flag to indicate if the end of the input has been found.
*/
private boolean eof;
/**
* current read index of the input.
*/
private long index;
/**
* current line of the input.
*/
private long line;
/**
* previous character read from the input.
*/
private char previous;
/**
* flag to indicate that a previous character was requested.
*/
private boolean usePrevious; private boolean usePrevious;
/** the number of characters read in the previous line. */ /**
* the number of characters read in the previous line.
*/
private long characterPreviousLine; private long characterPreviousLine;
@ -73,6 +90,7 @@ public class JSONTokener {
/** /**
* Construct a JSONTokener from an InputStream. The caller must close the input stream. * Construct a JSONTokener from an InputStream. The caller must close the input stream.
*
* @param inputStream The source. * @param inputStream The source.
*/ */
public JSONTokener(InputStream inputStream) { public JSONTokener(InputStream inputStream) {
@ -89,11 +107,31 @@ public class JSONTokener {
this(new StringReader(s)); this(new StringReader(s));
} }
/**
* Get the hex value of a character (base16).
*
* @param c A character between '0' and '9' or between 'A' and 'F' or
* between 'a' and 'f'.
* @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
public static int dehexchar(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - ('A' - 10);
}
if (c >= 'a' && c <= 'f') {
return c - ('a' - 10);
}
return -1;
}
/** /**
* Back up one character. This provides a sort of lookahead capability, * Back up one character. This provides a sort of lookahead capability,
* so that you can test for a digit or letter before attempting to parse * so that you can test for a digit or letter before attempting to parse
* the next number or identifier. * the next number or identifier.
*
* @throws JSONException Thrown if trying to step back more than 1 step * @throws JSONException Thrown if trying to step back more than 1 step
* or if already at the start of the string * or if already at the start of the string
*/ */
@ -119,25 +157,6 @@ public class JSONTokener {
} }
} }
/**
* Get the hex value of a character (base16).
* @param c A character between '0' and '9' or between 'A' and 'F' or
* between 'a' and 'f'.
* @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
public static int dehexchar(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - ('A' - 10);
}
if (c >= 'a' && c <= 'f') {
return c - ('a' - 10);
}
return -1;
}
/** /**
* Checks if the end of the input has been reached. * Checks if the end of the input has been reached.
* *
@ -151,6 +170,7 @@ public class JSONTokener {
/** /**
* Determine if the source string still contains characters that next() * Determine if the source string still contains characters that next()
* can consume. * can consume.
*
* @return true if not yet at the end of the source. * @return true if not yet at the end of the source.
* @throws JSONException thrown if there is an error stepping forward * @throws JSONException thrown if there is an error stepping forward
* or backward while checking for more data. * or backward while checking for more data.
@ -208,6 +228,7 @@ public class JSONTokener {
/** /**
* Increments the internal indexes according to the previous character * Increments the internal indexes according to the previous character
* read and the character passed as the current character. * read and the character passed as the current character.
*
* @param c the current character read. * @param c the current character read.
*/ */
private void incrementIndexes(int c) { private void incrementIndexes(int c) {
@ -232,6 +253,7 @@ public class JSONTokener {
/** /**
* Consume the next character, and check that it matches a specified * Consume the next character, and check that it matches a specified
* character. * character.
*
* @param c The character to match. * @param c The character to match.
* @return The character. * @return The character.
* @throws JSONException if the character does not match. * @throws JSONException if the character does not match.
@ -254,8 +276,7 @@ public class JSONTokener {
* *
* @param n The number of characters to take. * @param n The number of characters to take.
* @return A string of n characters. * @return A string of n characters.
* @throws JSONException * @throws JSONException Substring bounds error if there are not
* Substring bounds error if there are not
* n characters remaining in the source string. * n characters remaining in the source string.
*/ */
public String next(int n) throws JSONException { public String next(int n) throws JSONException {
@ -279,8 +300,9 @@ public class JSONTokener {
/** /**
* Get the next char in the string, skipping whitespace. * Get the next char in the string, skipping whitespace.
* @throws JSONException Thrown if there is an error reading the source string. *
* @return A character, or 0 if there are no more characters. * @return A character, or 0 if there are no more characters.
* @throws JSONException Thrown if there is an error reading the source string.
*/ */
public char nextClean() throws JSONException { public char nextClean() throws JSONException {
for (; ; ) { for (; ; ) {
@ -297,6 +319,7 @@ public class JSONTokener {
* Backslash processing is done. The formal JSON format does not * Backslash processing is done. The formal JSON format does not
* allow strings in single quotes, but an implementation is allowed to * allow strings in single quotes, but an implementation is allowed to
* accept them. * accept them.
*
* @param quote The quoting character, either * @param quote The quoting character, either
* <code>"</code>&nbsp;<small>(double quote)</small> or * <code>"</code>&nbsp;<small>(double quote)</small> or
* <code>'</code>&nbsp;<small>(single quote)</small>. * <code>'</code>&nbsp;<small>(single quote)</small>.
@ -361,6 +384,7 @@ public class JSONTokener {
/** /**
* Get the text up but not including the specified character or the * Get the text up but not including the specified character or the
* end of line, whichever comes first. * end of line, whichever comes first.
*
* @param delimiter A delimiter character. * @param delimiter A delimiter character.
* @return A string. * @return A string.
* @throws JSONException Thrown if there is an error while searching * @throws JSONException Thrown if there is an error while searching
@ -384,6 +408,7 @@ public class JSONTokener {
/** /**
* Get the text up but not including one of the specified delimiter * Get the text up but not including one of the specified delimiter
* characters or the end of line, whichever comes first. * characters or the end of line, whichever comes first.
*
* @param delimiters A set of delimiter characters. * @param delimiters A set of delimiter characters.
* @return A string, trimmed. * @return A string, trimmed.
* @throws JSONException Thrown if there is an error while searching * @throws JSONException Thrown if there is an error while searching
@ -409,9 +434,9 @@ public class JSONTokener {
/** /**
* Get the next value. The value can be a Boolean, Double, Integer, * Get the next value. The value can be a Boolean, Double, Integer,
* JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
* @throws JSONException If syntax error.
* *
* @return An object. * @return An object.
* @throws JSONException If syntax error.
*/ */
public Object nextValue() throws JSONException { public Object nextValue() throws JSONException {
char c = this.nextClean(); char c = this.nextClean();
@ -458,6 +483,7 @@ public class JSONTokener {
/** /**
* Skip characters until the next character is the requested character. * Skip characters until the next character is the requested character.
* If the requested character is not found, no characters are skipped. * If the requested character is not found, no characters are skipped.
*
* @param to A character to skip to. * @param to A character to skip to.
* @return The requested character, or zero if the requested character * @return The requested character, or zero if the requested character
* is not found. * is not found.

View File

@ -54,18 +54,16 @@ SOFTWARE.
* you. Objects and arrays can be nested up to 200 levels deep. * you. Objects and arrays can be nested up to 200 levels deep.
* <p> * <p>
* This can sometimes be easier than using a JSONObject to build a string. * This can sometimes be easier than using a JSONObject to build a string.
*
* @author JSON.org * @author JSON.org
* @version 2016-08-08 * @version 2016-08-08
*/ */
public class JSONWriter { public class JSONWriter {
private static final int maxdepth = 200; private static final int maxdepth = 200;
/** /**
* The comma flag determines if a comma should be output before the next * The object/array stack.
* value.
*/ */
private boolean comma; private final JSONObject stack[];
/** /**
* The current mode. Values: * The current mode. Values:
* 'a' (array), * 'a' (array),
@ -75,21 +73,19 @@ public class JSONWriter {
* 'o' (object). * 'o' (object).
*/ */
protected char mode; protected char mode;
/**
* The object/array stack.
*/
private final JSONObject stack[];
/**
* The stack top index. A value of 0 indicates that the stack is empty.
*/
private int top;
/** /**
* The writer that will receive the output. * The writer that will receive the output.
*/ */
protected Appendable writer; protected Appendable writer;
/**
* The comma flag determines if a comma should be output before the next
* value.
*/
private boolean comma;
/**
* The stack top index. A value of 0 indicates that the stack is empty.
*/
private int top;
/** /**
* Make a fresh JSONWriter. It can be used to build one JSON text. * Make a fresh JSONWriter. It can be used to build one JSON text.
@ -102,200 +98,6 @@ public class JSONWriter {
this.writer = w; this.writer = w;
} }
/**
* Append a value.
* @param string A string value.
* @return this
* @throws JSONException If the value is out of sequence.
*/
private JSONWriter append(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null pointer");
}
if (this.mode == 'o' || this.mode == 'a') {
try {
if (this.comma && this.mode == 'a') {
this.writer.append(',');
}
this.writer.append(string);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
if (this.mode == 'o') {
this.mode = 'k';
}
this.comma = true;
return this;
}
throw new JSONException("Value out of sequence.");
}
/**
* Begin appending a new array. All values until the balancing
* <code>endArray</code> will be appended to this array. The
* <code>endArray</code> method must be called to mark the array's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter array() throws JSONException {
if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
this.push(null);
this.append("[");
this.comma = false;
return this;
}
throw new JSONException("Misplaced array.");
}
/**
* End something.
* @param m Mode
* @param c Closing character
* @return this
* @throws JSONException If unbalanced.
*/
private JSONWriter end(char m, char c) throws JSONException {
if (this.mode != m) {
throw new JSONException(m == 'a'
? "Misplaced endArray."
: "Misplaced endObject.");
}
this.pop(m);
try {
this.writer.append(c);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
this.comma = true;
return this;
}
/**
* End an array. This method most be called to balance calls to
* <code>array</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endArray() throws JSONException {
return this.end('a', ']');
}
/**
* End an object. This method most be called to balance calls to
* <code>object</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endObject() throws JSONException {
return this.end('k', '}');
}
/**
* Append a key. The key will be associated with the next value. In an
* object, every value must be preceded by a key.
* @param string A key string.
* @return this
* @throws JSONException If the key is out of place. For example, keys
* do not belong in arrays or if the key is null.
*/
public JSONWriter key(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null key.");
}
if (this.mode == 'k') {
try {
JSONObject topObject = this.stack[this.top - 1];
// don't use the built in putOnce method to maintain Android support
if(topObject.has(string)) {
throw new JSONException("Duplicate key \"" + string + "\"");
}
topObject.put(string, true);
if (this.comma) {
this.writer.append(',');
}
this.writer.append(JSONObject.quote(string));
this.writer.append(':');
this.comma = false;
this.mode = 'o';
return this;
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
}
throw new JSONException("Misplaced key.");
}
/**
* Begin appending a new object. All keys and values until the balancing
* <code>endObject</code> will be appended to this object. The
* <code>endObject</code> method must be called to mark the object's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter object() throws JSONException {
if (this.mode == 'i') {
this.mode = 'o';
}
if (this.mode == 'o' || this.mode == 'a') {
this.append("{");
this.push(new JSONObject());
this.comma = false;
return this;
}
throw new JSONException("Misplaced object.");
}
/**
* Pop an array or object scope.
* @param c The scope to close.
* @throws JSONException If nesting is wrong.
*/
private void pop(char c) throws JSONException {
if (this.top <= 0) {
throw new JSONException("Nesting error.");
}
char m = this.stack[this.top - 1] == null ? 'a' : 'k';
if (m != c) {
throw new JSONException("Nesting error.");
}
this.top -= 1;
this.mode = this.top == 0
? 'd'
: this.stack[this.top - 1] == null
? 'a'
: 'k';
}
/**
* Push an array or object scope.
* @param jo The scope to open.
* @throws JSONException If nesting is too deep.
*/
private void push(JSONObject jo) throws JSONException {
if (this.top >= maxdepth) {
throw new JSONException("Nesting too deep.");
}
this.stack[this.top] = jo;
this.mode = jo == null ? 'a' : 'k';
this.top += 1;
}
/** /**
* Make a JSON text of an Object value. If the object has an * Make a JSON text of an Object value. If the object has an
* value.toJSONString() method, then that method will be used to produce the * value.toJSONString() method, then that method will be used to produce the
@ -311,14 +113,12 @@ public class JSONWriter {
* <p> * <p>
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* *
* @param value * @param value The value to be serialized.
* The value to be serialized.
* @return a printable, displayable, transmittable representation of the * @return a printable, displayable, transmittable representation of the
* object, beginning with <code>{</code>&nbsp;<small>(left * object, beginning with <code>{</code>&nbsp;<small>(left
* brace)</small> and ending with <code>}</code>&nbsp;<small>(right * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
* brace)</small>. * brace)</small>.
* @throws JSONException * @throws JSONException If the value is or contains an invalid number.
* If the value is or contains an invalid number.
*/ */
public static String valueToString(Object value) throws JSONException { public static String valueToString(Object value) throws JSONException {
if (value == null || value.equals(null)) { if (value == null || value.equals(null)) {
@ -368,9 +168,211 @@ public class JSONWriter {
return JSONObject.quote(value.toString()); return JSONObject.quote(value.toString());
} }
/**
* Append a value.
*
* @param string A string value.
* @return this
* @throws JSONException If the value is out of sequence.
*/
private JSONWriter append(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null pointer");
}
if (this.mode == 'o' || this.mode == 'a') {
try {
if (this.comma && this.mode == 'a') {
this.writer.append(',');
}
this.writer.append(string);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
if (this.mode == 'o') {
this.mode = 'k';
}
this.comma = true;
return this;
}
throw new JSONException("Value out of sequence.");
}
/**
* Begin appending a new array. All values until the balancing
* <code>endArray</code> will be appended to this array. The
* <code>endArray</code> method must be called to mark the array's end.
*
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter array() throws JSONException {
if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
this.push(null);
this.append("[");
this.comma = false;
return this;
}
throw new JSONException("Misplaced array.");
}
/**
* End something.
*
* @param m Mode
* @param c Closing character
* @return this
* @throws JSONException If unbalanced.
*/
private JSONWriter end(char m, char c) throws JSONException {
if (this.mode != m) {
throw new JSONException(m == 'a'
? "Misplaced endArray."
: "Misplaced endObject.");
}
this.pop(m);
try {
this.writer.append(c);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
this.comma = true;
return this;
}
/**
* End an array. This method most be called to balance calls to
* <code>array</code>.
*
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endArray() throws JSONException {
return this.end('a', ']');
}
/**
* End an object. This method most be called to balance calls to
* <code>object</code>.
*
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endObject() throws JSONException {
return this.end('k', '}');
}
/**
* Append a key. The key will be associated with the next value. In an
* object, every value must be preceded by a key.
*
* @param string A key string.
* @return this
* @throws JSONException If the key is out of place. For example, keys
* do not belong in arrays or if the key is null.
*/
public JSONWriter key(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null key.");
}
if (this.mode == 'k') {
try {
JSONObject topObject = this.stack[this.top - 1];
// don't use the built in putOnce method to maintain Android support
if (topObject.has(string)) {
throw new JSONException("Duplicate key \"" + string + "\"");
}
topObject.put(string, true);
if (this.comma) {
this.writer.append(',');
}
this.writer.append(JSONObject.quote(string));
this.writer.append(':');
this.comma = false;
this.mode = 'o';
return this;
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
}
throw new JSONException("Misplaced key.");
}
/**
* Begin appending a new object. All keys and values until the balancing
* <code>endObject</code> will be appended to this object. The
* <code>endObject</code> method must be called to mark the object's end.
*
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter object() throws JSONException {
if (this.mode == 'i') {
this.mode = 'o';
}
if (this.mode == 'o' || this.mode == 'a') {
this.append("{");
this.push(new JSONObject());
this.comma = false;
return this;
}
throw new JSONException("Misplaced object.");
}
/**
* Pop an array or object scope.
*
* @param c The scope to close.
* @throws JSONException If nesting is wrong.
*/
private void pop(char c) throws JSONException {
if (this.top <= 0) {
throw new JSONException("Nesting error.");
}
char m = this.stack[this.top - 1] == null ? 'a' : 'k';
if (m != c) {
throw new JSONException("Nesting error.");
}
this.top -= 1;
this.mode = this.top == 0
? 'd'
: this.stack[this.top - 1] == null
? 'a'
: 'k';
}
/**
* Push an array or object scope.
*
* @param jo The scope to open.
* @throws JSONException If nesting is too deep.
*/
private void push(JSONObject jo) throws JSONException {
if (this.top >= maxdepth) {
throw new JSONException("Nesting too deep.");
}
this.stack[this.top] = jo;
this.mode = jo == null ? 'a' : 'k';
this.top += 1;
}
/** /**
* Append either the value <code>true</code> or the value * Append either the value <code>true</code> or the value
* <code>false</code>. * <code>false</code>.
*
* @param b A boolean. * @param b A boolean.
* @return this * @return this
* @throws JSONException * @throws JSONException
@ -381,6 +383,7 @@ public class JSONWriter {
/** /**
* Append a double value. * Append a double value.
*
* @param d A double. * @param d A double.
* @return this * @return this
* @throws JSONException If the number is not finite. * @throws JSONException If the number is not finite.
@ -391,6 +394,7 @@ public class JSONWriter {
/** /**
* Append a long value. * Append a long value.
*
* @param l A long. * @param l A long.
* @return this * @return this
* @throws JSONException * @throws JSONException
@ -402,6 +406,7 @@ public class JSONWriter {
/** /**
* Append an object value. * Append an object value.
*
* @param object The object to append. It can be null, or a Boolean, Number, * @param object The object to append. It can be null, or a Boolean, Number,
* String, JSONObject, or JSONArray, or an object that implements JSONString. * String, JSONObject, or JSONArray, or an object that implements JSONString.
* @return this * @return this

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.