mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-27 21:10:54 +00:00
Merge remote-tracking branch 'origin/development' into development
This commit is contained in:
commit
e60cf79309
@ -110,8 +110,7 @@ There is a dummy user named "Server" in every player's friends list that you can
|
|||||||
| broadcast | broadcast \<message> | server.broadcast | Both side | Sends a message to all the players. | b |
|
| broadcast | broadcast \<message> | server.broadcast | Both side | Sends a message to all the players. | b |
|
||||||
| coop | coop \<playerId> \<target playerId> | server.coop | Both side | Forces someone to join the world of others. | |
|
| coop | coop \<playerId> \<target playerId> | server.coop | Both side | Forces someone to join the world of others. | |
|
||||||
| changescene | changescene \<scene id> | player.changescene | Client only | Switch scenes by scene ID. | scene |
|
| changescene | changescene \<scene id> | player.changescene | Client only | Switch scenes by scene ID. | scene |
|
||||||
| clearartifacts | clearartifacts | player.clearartifacts | Client only | Deletes all unequipped and unlocked level 0 artifacts, including 5-star rarity ones from your inventory. | clearart |
|
| clear | clear <all\|wp\|art\|mat> [UID] | player.clearinv | Client only | Deletes all unequipped and unlocked level 0 artifacts(art)/weapons(wp)/material(all) or all, including 5-star rarity ones from your inventory. | clear |
|
||||||
| clearweapons | clearweapons | player.clearweapons | Client only | Deletes all unequipped and unlocked weapons, including 5-star rarity ones from your inventory. | clearwpns |
|
|
||||||
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
|
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
|
||||||
| give | give [player] <itemId\|itemName> [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` |
|
| give | give [player] <itemId\|itemName> [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` |
|
||||||
| givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec |
|
| givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec |
|
||||||
|
@ -111,8 +111,7 @@ chmod +x gradlew
|
|||||||
| broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b |
|
| broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b |
|
||||||
| coop | coop \<uid> <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | |
|
| coop | coop \<uid> <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | |
|
||||||
| changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene |
|
| changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene |
|
||||||
| clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart |
|
| clear | clear <all\|wp\|art\|mat> [UID] | player.clearinv | 仅客户端 | 删除所有未装备及未解锁的圣遗物(art)或武器(wp)或材料(mat)或者所有(all),包括五星 | clear |
|
||||||
| clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp |
|
|
||||||
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
|
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
|
||||||
| give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` |
|
| give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` |
|
||||||
| givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
|
| givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
|
||||||
|
176
data/gacha_records.html
Normal file
176
data/gacha_records.html
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
// Debug entry
|
||||||
|
// record = [
|
||||||
|
// {"time": 10000341, "item": 1001},
|
||||||
|
// {"time": 10000342, "item": 1002},
|
||||||
|
// {"time": 10000343, "item": 1003},
|
||||||
|
// ];
|
||||||
|
// maxPage = 5;
|
||||||
|
|
||||||
|
// in production environment
|
||||||
|
record = {{REPLACE_RECORD}};
|
||||||
|
maxPage = {{REPLACE_MAXPAGE}};
|
||||||
|
|
||||||
|
// TODO: implement this mapper by yourself
|
||||||
|
// I don't want to put real items' name here to avoid being DMCA'd
|
||||||
|
mappings = {
|
||||||
|
'en-us': {
|
||||||
|
200: "Standard",
|
||||||
|
301: "Event Avatar",
|
||||||
|
302: "Event Weapon",
|
||||||
|
1041 : ["M0n4", "yellow"],
|
||||||
|
1032 : ["B4nn477", "purple"],
|
||||||
|
1035 : ["77", "yellow"]
|
||||||
|
},
|
||||||
|
'zh-cn': {
|
||||||
|
// encoding issues here, maybe we should consider load mappings remotely
|
||||||
|
// will display as "锟斤铐锟斤铐锟斤铐", lmao
|
||||||
|
// 200: "常驻",
|
||||||
|
// 301: "角色UP-1",
|
||||||
|
// 302: "武器UP"
|
||||||
|
200: "Standard",
|
||||||
|
301: "Event Avatar",
|
||||||
|
302: "Event Weapon",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mappings['default'] = mappings['en-us'];
|
||||||
|
</script>
|
||||||
|
<!-- TODO: Refine the CSS -->
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 400px;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .navbar {
|
||||||
|
margin: auto;
|
||||||
|
width: fit-content;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellow {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
color: rgb(75, 107, 251);
|
||||||
|
}
|
||||||
|
|
||||||
|
.purple {
|
||||||
|
color: rgb(242, 40, 242);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background: skyblue;">
|
||||||
|
<div class="content">
|
||||||
|
<h1>Gacha Records</h1>
|
||||||
|
<h2 id="gacha-type"></h2>
|
||||||
|
<br/>
|
||||||
|
<div style="width: fit-content">
|
||||||
|
<table border="1">
|
||||||
|
<tbody id="container">
|
||||||
|
<tr>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Item</th>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="navbar">
|
||||||
|
<a href="" id="prev"> < </a>
|
||||||
|
<span id="curpage">1</span>
|
||||||
|
<a href="" id="next"> > </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var lang = new window.URLSearchParams(window.location.search).get("lang");
|
||||||
|
function itemMapper(itemID) {
|
||||||
|
if (mappings[lang] != null && mappings[lang][itemID] != null) {
|
||||||
|
var entry = mappings[lang][itemID];
|
||||||
|
if (entry){
|
||||||
|
return "<span class='" + entry[1] + "'>" + entry[0] + "</span>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mappings['default'][itemID] != null) {
|
||||||
|
var entry = mappings['default'][itemID];
|
||||||
|
if (entry){
|
||||||
|
return "<span class='" + entry[1] + "'>" + entry[0] + "</span>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "<span class='blue'>" + itemID + "</span>";
|
||||||
|
}
|
||||||
|
function dateFormatter(timeStamp) {
|
||||||
|
var date = new Date(timeStamp);
|
||||||
|
if (lang == "en-us" || lang == null) { // MM/DD/YYYY hh:mm:ss.SSS
|
||||||
|
return String(date.getMonth()+1).padStart(2, "0") +
|
||||||
|
"/"+String(date.getDate()).padStart(2, "0")+
|
||||||
|
"/"+date.getFullYear()+
|
||||||
|
" "+String(date.getHours()).padStart(2, "0")+
|
||||||
|
":"+String(date.getMinutes()).padStart(2, "0")+
|
||||||
|
":"+String(date.getSeconds()).padStart(2, "0")+
|
||||||
|
"."+date.getMilliseconds();
|
||||||
|
} else if (lang == "zh-cn") { // YYYY/MM/DD hh:mm:ss.SSS
|
||||||
|
return date.getFullYear()+
|
||||||
|
"/" + String(date.getMonth()+1).padStart(2, "0") +
|
||||||
|
"/"+String(date.getDate()).padStart(2, "0")+
|
||||||
|
" "+String(date.getHours()).padStart(2, "0")+
|
||||||
|
":"+String(date.getMinutes()).padStart(2, "0")+
|
||||||
|
":"+String(date.getSeconds()).padStart(2, "0")+
|
||||||
|
"."+date.getMilliseconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(function (){
|
||||||
|
var container = document.getElementById("container");
|
||||||
|
record.forEach(element => {
|
||||||
|
var e = document.createElement("tr");
|
||||||
|
|
||||||
|
e.innerHTML= "<td>" + dateFormatter(element.time) + "</td><td>" + itemMapper(element.item) + "</td>";
|
||||||
|
container.appendChild(e);
|
||||||
|
});
|
||||||
|
// setup pagenation buttons
|
||||||
|
var page = parseInt(new window.URLSearchParams(window.location.search).get("p"));
|
||||||
|
if (!page){
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
document.getElementById("curpage").innerText = page + 1;
|
||||||
|
var href = new URL(window.location);
|
||||||
|
href.searchParams.set("p", page - 1);
|
||||||
|
document.getElementById("prev").href = href.toString();
|
||||||
|
href.searchParams.set("p", page + 1);
|
||||||
|
document.getElementById("next").href = href.toString();
|
||||||
|
|
||||||
|
if (page <= 0) {
|
||||||
|
document.getElementById("prev").style.display = "none";
|
||||||
|
}
|
||||||
|
if (page >= maxPage - 1) {
|
||||||
|
document.getElementById("next").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup gacha type info
|
||||||
|
var gachaType = new window.URLSearchParams(window.location.search).get("gachaType");
|
||||||
|
var gachaString;
|
||||||
|
if (mappings[lang] != null && mappings[lang][gachaType] != null) {
|
||||||
|
gachaString = mappings[lang][gachaType];
|
||||||
|
}else{
|
||||||
|
gachaString = mappings['default'][gachaType];
|
||||||
|
if (gachaString == null) {
|
||||||
|
gachaString = gachaType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById("gacha-type").innerText = gachaString;
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -3,6 +3,5 @@ syntax = "proto3";
|
|||||||
option java_package = "emu.grasscutter.net.proto";
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
message McoinExchangeHcoinRsp {
|
message McoinExchangeHcoinRsp {
|
||||||
uint32 mCoinNum = 1;
|
int32 retcode = 1;
|
||||||
uint32 hCoinNum = 2;
|
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,12 @@ public final class GiveCharCommand implements CommandHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check level.
|
||||||
|
if (level > 90) {
|
||||||
|
CommandHandler.sendMessage(sender, "Invalid avatar level.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate ascension level.
|
// Calculate ascension level.
|
||||||
if (level <= 40) {
|
if (level <= 40) {
|
||||||
ascension = (int) Math.ceil(level / 20f);
|
ascension = (int) Math.ceil(level / 20f);
|
||||||
@ -88,6 +94,6 @@ public final class GiveCharCommand implements CommandHandler {
|
|||||||
avatar.recalcStats();
|
avatar.recalcStats();
|
||||||
|
|
||||||
targetPlayer.addAvatar(avatar);
|
targetPlayer.addAvatar(avatar);
|
||||||
CommandHandler.sendMessage(sender, String.format("Given %s to %s.", avatarId, target));
|
CommandHandler.sendMessage(sender, String.format("Given %s with level %s to %s.", avatarId, level, target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,21 @@ public final class SetStatsCommand implements CommandHandler {
|
|||||||
String stat = args.get(0);
|
String stat = args.get(0);
|
||||||
switch (stat) {
|
switch (stat) {
|
||||||
default:
|
default:
|
||||||
CommandHandler.sendMessage(sender, "Usage: /setstats|stats <hp | def | atk | em | er | crate | cdmg> <value> for basic stats");
|
CommandHandler.sendMessage(sender, "Usage: /setstats|stats <hp | mhp | def | atk | em | er | crate | cdmg> <value> for basic stats");
|
||||||
CommandHandler.sendMessage(sender, "Usage: /stats <epyro | ecryo | ehydro | egeo | edend | eelec | ephys> <amount> for elemental bonus");
|
CommandHandler.sendMessage(sender, "Usage: /stats <epyro | ecryo | ehydro | egeo | edend | eelec | ephys> <amount> for elemental bonus");
|
||||||
return;
|
return;
|
||||||
|
case "mhp":
|
||||||
|
try {
|
||||||
|
int health = Integer.parseInt(args.get(1));
|
||||||
|
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
|
||||||
|
entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, health);
|
||||||
|
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_MAX_HP));
|
||||||
|
CommandHandler.sendMessage(sender, "MAX HP set to " + health + ".");
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(sender, "Invalid Max HP value.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "hp":
|
case "hp":
|
||||||
try {
|
try {
|
||||||
int health = Integer.parseInt(args.get(1));
|
int health = Integer.parseInt(args.get(1));
|
||||||
|
@ -53,7 +53,7 @@ public final class TalentCommand implements CommandHandler {
|
|||||||
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
|
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nextLevel > 16){
|
if (nextLevel >= 16){
|
||||||
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
|
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ public final class TalentCommand implements CommandHandler {
|
|||||||
CommandHandler.sendMessage(sender, "To set talent level: /talent <n or e or q> <value>");
|
CommandHandler.sendMessage(sender, "To set talent level: /talent <n or e or q> <value>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nextLevel > 16){
|
if (nextLevel >= 16){
|
||||||
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
|
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,14 @@ package emu.grasscutter.database;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.mongodb.client.result.DeleteResult;
|
import com.mongodb.client.result.DeleteResult;
|
||||||
|
import dev.morphia.query.FindOptions;
|
||||||
|
import dev.morphia.query.Sort;
|
||||||
import dev.morphia.query.experimental.filters.Filters;
|
import dev.morphia.query.experimental.filters.Filters;
|
||||||
import emu.grasscutter.GameConstants;
|
import emu.grasscutter.GameConstants;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.friends.Friendship;
|
import emu.grasscutter.game.friends.Friendship;
|
||||||
|
import emu.grasscutter.game.gacha.GachaRecord;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
@ -78,6 +81,11 @@ public final class DatabaseHelper {
|
|||||||
return DatabaseManager.getDatastore().find(Account.class).filter(Filters.eq("token", token)).first();
|
return DatabaseManager.getDatastore().find(Account.class).filter(Filters.eq("token", token)).first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Account getAccountBySessionKey(String sessionKey) {
|
||||||
|
if(sessionKey == null) return null;
|
||||||
|
return DatabaseManager.getDatastore().find(Account.class).filter(Filters.eq("sessionKey", sessionKey)).first();
|
||||||
|
}
|
||||||
|
|
||||||
public static Account getAccountById(String uid) {
|
public static Account getAccountById(String uid) {
|
||||||
return DatabaseManager.getDatastore().find(Account.class).filter(Filters.eq("_id", uid)).first();
|
return DatabaseManager.getDatastore().find(Account.class).filter(Filters.eq("_id", uid)).first();
|
||||||
}
|
}
|
||||||
@ -181,5 +189,36 @@ public final class DatabaseHelper {
|
|||||||
)).first();
|
)).first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<GachaRecord> getGachaRecords(int ownerId, int page, int gachaType){
|
||||||
|
return getGachaRecords(ownerId, page, gachaType, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<GachaRecord> getGachaRecords(int ownerId, int page, int gachaType, int pageSize){
|
||||||
|
return DatabaseManager.getDatastore().find(GachaRecord.class).filter(
|
||||||
|
Filters.eq("ownerId", ownerId),
|
||||||
|
Filters.eq("gachaType", gachaType)
|
||||||
|
).iterator(new FindOptions()
|
||||||
|
.sort(Sort.descending("transactionDate"))
|
||||||
|
.skip(pageSize * page)
|
||||||
|
.limit(pageSize)
|
||||||
|
).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getGachaRecordsMaxPage(int ownerId, int page, int gachaType){
|
||||||
|
return getGachaRecordsMaxPage(ownerId, page, gachaType, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getGachaRecordsMaxPage(int ownerId, int page, int gachaType, int pageSize){
|
||||||
|
long count = DatabaseManager.getDatastore().find(GachaRecord.class).filter(
|
||||||
|
Filters.eq("ownerId", ownerId),
|
||||||
|
Filters.eq("gachaType", gachaType)
|
||||||
|
).count();
|
||||||
|
return count / 10 + (count % 10 > 0 ? 1 : 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveGachaRecord(GachaRecord gachaRecord){
|
||||||
|
DatabaseManager.getDatastore().save(gachaRecord);
|
||||||
|
}
|
||||||
|
|
||||||
public static char AWJVN = 'e';
|
public static char AWJVN = 'e';
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import emu.grasscutter.Grasscutter.ServerRunMode;
|
|||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.friends.Friendship;
|
import emu.grasscutter.game.friends.Friendship;
|
||||||
|
import emu.grasscutter.game.gacha.GachaRecord;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ public final class DatabaseManager {
|
|||||||
private static Datastore dispatchDatastore;
|
private static Datastore dispatchDatastore;
|
||||||
|
|
||||||
private static final Class<?>[] mappedClasses = new Class<?>[] {
|
private static final Class<?>[] mappedClasses = new Class<?>[] {
|
||||||
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class
|
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, GachaRecord.class
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Datastore getDatastore() {
|
public static Datastore getDatastore() {
|
||||||
|
@ -74,7 +74,11 @@ public class Account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
|
if(email != null && !email.isEmpty()) {
|
||||||
return email;
|
return email;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmail(String email) {
|
public void setEmail(String email) {
|
||||||
|
@ -91,9 +91,21 @@ public class GachaBanner {
|
|||||||
return eventChance;
|
return eventChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public GachaInfo toProto() {
|
public GachaInfo toProto() {
|
||||||
String record = "http://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + "/gacha";
|
return toProto("");
|
||||||
|
}
|
||||||
|
public GachaInfo toProto(String sessionKey) {
|
||||||
|
String record = "https://"
|
||||||
|
+ (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ?
|
||||||
|
Grasscutter.getConfig().getDispatchOptions().Ip :
|
||||||
|
Grasscutter.getConfig().getDispatchOptions().PublicIp)
|
||||||
|
+ ":"
|
||||||
|
+ Integer.toString(Grasscutter.getConfig().getDispatchOptions().PublicPort == 0 ?
|
||||||
|
Grasscutter.getConfig().getDispatchOptions().Port :
|
||||||
|
Grasscutter.getConfig().getDispatchOptions().PublicPort)
|
||||||
|
+ "/gacha?s=" + sessionKey + "&gachaType=" + gachaType;
|
||||||
|
// Grasscutter.getLogger().info("record = " + record);
|
||||||
GachaInfo.Builder info = GachaInfo.newBuilder()
|
GachaInfo.Builder info = GachaInfo.newBuilder()
|
||||||
.setGachaType(this.getGachaType())
|
.setGachaType(this.getGachaType())
|
||||||
.setScheduleId(this.getScheduleId())
|
.setScheduleId(this.getScheduleId())
|
||||||
|
@ -14,6 +14,7 @@ import com.sun.nio.file.SensitivityWatchEventModifier;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.def.ItemData;
|
import emu.grasscutter.data.def.ItemData;
|
||||||
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.gacha.GachaBanner.BannerType;
|
import emu.grasscutter.game.gacha.GachaBanner.BannerType;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
@ -197,6 +198,10 @@ public class GachaManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write gacha record
|
||||||
|
GachaRecord gachaRecord = new GachaRecord(itemId, player.getUid(), gachaType);
|
||||||
|
DatabaseHelper.saveGachaRecord(gachaRecord);
|
||||||
|
|
||||||
// Create gacha item
|
// Create gacha item
|
||||||
GachaItem.Builder gachaItem = GachaItem.newBuilder();
|
GachaItem.Builder gachaItem = GachaItem.newBuilder();
|
||||||
int addStardust = 0, addStarglitter = 0;
|
int addStardust = 0, addStarglitter = 0;
|
||||||
@ -321,6 +326,7 @@ public class GachaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private synchronized GetGachaInfoRsp createProto() {
|
private synchronized GetGachaInfoRsp createProto() {
|
||||||
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
||||||
|
|
||||||
@ -331,11 +337,25 @@ public class GachaManager {
|
|||||||
return proto.build();
|
return proto.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized GetGachaInfoRsp createProto(String sessionKey) {
|
||||||
|
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
||||||
|
|
||||||
|
for (GachaBanner banner : getGachaBanners().values()) {
|
||||||
|
proto.addGachaInfoList(banner.toProto(sessionKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public GetGachaInfoRsp toProto() {
|
public GetGachaInfoRsp toProto() {
|
||||||
if (this.cachedProto == null) {
|
if (this.cachedProto == null) {
|
||||||
this.cachedProto = createProto();
|
this.cachedProto = createProto();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.cachedProto;
|
return this.cachedProto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetGachaInfoRsp toProto(String sessionKey) {
|
||||||
|
return createProto(sessionKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
75
src/main/java/emu/grasscutter/game/gacha/GachaRecord.java
Normal file
75
src/main/java/emu/grasscutter/game/gacha/GachaRecord.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package emu.grasscutter.game.gacha;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.*;
|
||||||
|
|
||||||
|
@Entity(value = "gachas", useDiscriminator = false)
|
||||||
|
public class GachaRecord {
|
||||||
|
@Id private ObjectId id;
|
||||||
|
|
||||||
|
@Indexed private int ownerId;
|
||||||
|
|
||||||
|
private Date transactionDate;
|
||||||
|
private int itemID;
|
||||||
|
@Indexed private int gachaType;
|
||||||
|
|
||||||
|
public GachaRecord() {}
|
||||||
|
|
||||||
|
public GachaRecord(int itemId ,int ownerId, int gachaType){
|
||||||
|
this.transactionDate = new Date();
|
||||||
|
this.itemID = itemId;
|
||||||
|
this.ownerId = ownerId;
|
||||||
|
this.gachaType = gachaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOwnerId() {
|
||||||
|
return ownerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwnerId(int ownerId) {
|
||||||
|
this.ownerId = ownerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGachaType() {
|
||||||
|
return gachaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGachaType(int type) {
|
||||||
|
this.gachaType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTransactionDate() {
|
||||||
|
return transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionDate(Date transactionDate) {
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemID() {
|
||||||
|
return itemID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemID(int itemID) {
|
||||||
|
this.itemID = itemID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectId getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(ObjectId id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return toJsonString();
|
||||||
|
}
|
||||||
|
public String toJsonString() {
|
||||||
|
return "{\"time\": " + this.transactionDate.getTime() + ",\"item\":" + this.itemID + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,7 +32,7 @@ public final class DispatchHttpJsonHandler implements HttpContextHandler {
|
|||||||
public void handle(Request req, Response res) throws IOException {
|
public void handle(Request req, Response res) throws IOException {
|
||||||
// Checking for ALL here isn't required as when ALL is enabled enableDevLogging() gets enabled
|
// Checking for ALL here isn't required as when ALL is enabled enableDevLogging() gets enabled
|
||||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> x == req.baseUrl())) {
|
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> x == req.baseUrl())) {
|
||||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s %s request: ", req.ip(), req.method(), req.baseUrl()) + (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s %s request: %s", req.ip(), req.method(), req.baseUrl()) + (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||||
}
|
}
|
||||||
res.send(response);
|
res.send(response);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import emu.grasscutter.server.dispatch.json.*;
|
|||||||
import emu.grasscutter.server.dispatch.json.ComboTokenReqJson.LoginTokenData;
|
import emu.grasscutter.server.dispatch.json.ComboTokenReqJson.LoginTokenData;
|
||||||
import emu.grasscutter.server.event.dispatch.QueryAllRegionsEvent;
|
import emu.grasscutter.server.event.dispatch.QueryAllRegionsEvent;
|
||||||
import emu.grasscutter.server.event.dispatch.QueryCurrentRegionEvent;
|
import emu.grasscutter.server.event.dispatch.QueryCurrentRegionEvent;
|
||||||
|
import emu.grasscutter.server.http.gacha.GachaRecordHandler;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import express.Express;
|
import express.Express;
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
@ -319,9 +320,6 @@ public final class DispatchServer {
|
|||||||
responseData.data.account.uid = account.getId();
|
responseData.data.account.uid = account.getId();
|
||||||
responseData.data.account.token = account.generateSessionKey();
|
responseData.data.account.token = account.generateSessionKey();
|
||||||
responseData.data.account.email = account.getEmail();
|
responseData.data.account.email = account.getEmail();
|
||||||
if (responseData.data.account.email == null) {
|
|
||||||
responseData.data.account.email = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.info(String.format("[Dispatch] Client %s failed to log in: Account %s created",
|
.info(String.format("[Dispatch] Client %s failed to log in: Account %s created",
|
||||||
@ -346,9 +344,6 @@ public final class DispatchServer {
|
|||||||
responseData.data.account.uid = account.getId();
|
responseData.data.account.uid = account.getId();
|
||||||
responseData.data.account.token = account.generateSessionKey();
|
responseData.data.account.token = account.generateSessionKey();
|
||||||
responseData.data.account.email = account.getEmail();
|
responseData.data.account.email = account.getEmail();
|
||||||
if (responseData.data.account.email == null) {
|
|
||||||
responseData.data.account.email = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", req.ip(),
|
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", req.ip(),
|
||||||
responseData.data.account.uid));
|
responseData.data.account.uid));
|
||||||
@ -389,9 +384,6 @@ public final class DispatchServer {
|
|||||||
responseData.data.account.uid = requestData.uid;
|
responseData.data.account.uid = requestData.uid;
|
||||||
responseData.data.account.token = requestData.token;
|
responseData.data.account.token = requestData.token;
|
||||||
responseData.data.account.email = account.getEmail();
|
responseData.data.account.email = account.getEmail();
|
||||||
if (responseData.data.account.email == null) { // null will trigger crash in some client
|
|
||||||
responseData.data.account.email = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s",
|
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s",
|
||||||
req.ip(), responseData.data.account.uid));
|
req.ip(), responseData.data.account.uid));
|
||||||
@ -494,7 +486,7 @@ public final class DispatchServer {
|
|||||||
// webstatic-sea.hoyoverse.com
|
// webstatic-sea.hoyoverse.com
|
||||||
httpServer.get("/admin/mi18n/plat_oversea/m202003048/m202003048-version.json", new DispatchHttpJsonHandler("{\"version\":51}"));
|
httpServer.get("/admin/mi18n/plat_oversea/m202003048/m202003048-version.json", new DispatchHttpJsonHandler("{\"version\":51}"));
|
||||||
|
|
||||||
httpServer.get("/gacha", (req, res) -> res.send("<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"));
|
httpServer.get("/gacha", new GachaRecordHandler());
|
||||||
|
|
||||||
httpServer.listen(Grasscutter.getConfig().getDispatchOptions().Port);
|
httpServer.listen(Grasscutter.getConfig().getDispatchOptions().Port);
|
||||||
Grasscutter.getLogger().info("[Dispatch] Dispatch server started on port " + httpServer.raw().port());
|
Grasscutter.getLogger().info("[Dispatch] Dispatch server started on port " + httpServer.raw().port());
|
||||||
|
@ -16,7 +16,7 @@ public class LoginResultJson {
|
|||||||
public static class VerifyAccountData {
|
public static class VerifyAccountData {
|
||||||
public String uid;
|
public String uid;
|
||||||
public String name = "";
|
public String name = "";
|
||||||
public String email;
|
public String email = "";
|
||||||
public String mobile = "";
|
public String mobile = "";
|
||||||
public String is_email_verify = "0";
|
public String is_email_verify = "0";
|
||||||
public String realname = "";
|
public String realname = "";
|
||||||
|
@ -23,21 +23,15 @@ public class GameServerPacketHandler {
|
|||||||
this.registerHandlers(handlerClass);
|
this.registerHandlers(handlerClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
|
public void registerPacketHandler(Class<? extends PacketHandler> handlerClass) {
|
||||||
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
|
|
||||||
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
|
|
||||||
|
|
||||||
for (Object obj : handlerClasses) {
|
|
||||||
Class<?> c = (Class<?>) obj;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Opcodes opcode = c.getAnnotation(Opcodes.class);
|
Opcodes opcode = handlerClass.getAnnotation(Opcodes.class);
|
||||||
|
|
||||||
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
|
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketHandler packetHandler = (PacketHandler) c.newInstance();
|
PacketHandler packetHandler = (PacketHandler) handlerClass.newInstance();
|
||||||
|
|
||||||
this.handlers.put(opcode.value(), packetHandler);
|
this.handlers.put(opcode.value(), packetHandler);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -45,6 +39,14 @@ public class GameServerPacketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
|
||||||
|
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
|
||||||
|
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
|
||||||
|
|
||||||
|
for (Object obj : handlerClasses) {
|
||||||
|
this.registerPacketHandler((Class<? extends PacketHandler>) obj);
|
||||||
|
}
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
Grasscutter.getLogger().info("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
|
Grasscutter.getLogger().info("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package emu.grasscutter.server.http.gacha;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
|
import emu.grasscutter.game.Account;
|
||||||
|
import emu.grasscutter.utils.FileUtils;
|
||||||
|
import express.http.HttpContextHandler;
|
||||||
|
import express.http.Request;
|
||||||
|
import express.http.Response;
|
||||||
|
|
||||||
|
public final class GachaRecordHandler implements HttpContextHandler {
|
||||||
|
String render_template;
|
||||||
|
public GachaRecordHandler() {
|
||||||
|
File template = new File(Grasscutter.getConfig().DATA_FOLDER + "gacha_records.html");
|
||||||
|
if (template.exists()) {
|
||||||
|
// Load from cache
|
||||||
|
render_template = new String(FileUtils.read(template));
|
||||||
|
} else {
|
||||||
|
render_template = "{{REPLACE_RECORD}}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Request req, Response res) throws IOException {
|
||||||
|
// Grasscutter.getLogger().info( req.query().toString() );
|
||||||
|
String sessionKey = req.query("s");
|
||||||
|
int page = 0;
|
||||||
|
int gachaType = 0;
|
||||||
|
if (req.query("p") != null) {
|
||||||
|
page = Integer.valueOf(req.query("p"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.query("gachaType") != null) {
|
||||||
|
gachaType = Integer.valueOf(req.query("gachaType"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
|
||||||
|
if (account != null) {
|
||||||
|
String records = DatabaseHelper.getGachaRecords(account.getPlayerUid(), page, gachaType).toString();
|
||||||
|
// Grasscutter.getLogger().info(records);
|
||||||
|
String response = render_template.replace("{{REPLACE_RECORD}}", records)
|
||||||
|
.replace("{{REPLACE_MAXPAGE}}", String.valueOf(DatabaseHelper.getGachaRecordsMaxPage(account.getPlayerUid(), page, gachaType)));
|
||||||
|
|
||||||
|
res.send(response);
|
||||||
|
} else {
|
||||||
|
res.send("404");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,7 +54,7 @@ public class HandlerBuyGoodsReq extends PacketHandler {
|
|||||||
session.getPlayer().save();
|
session.getPlayer().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bought + buyGoodsReq.getBoughtNum() > sg.getBuyLimit()) {
|
if ((bought + buyGoodsReq.getBoughtNum() > sg.getBuyLimit()) && sg.getBuyLimit() != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@ public class HandlerGetGachaInfoReq extends PacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaManager()));
|
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaManager(),
|
||||||
|
// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
|
||||||
|
session.getPlayer().getAccount().getSessionKey())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import emu.grasscutter.net.packet.Opcodes;
|
|||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.McoinExchangeHcoinReqOuterClass;
|
import emu.grasscutter.net.proto.McoinExchangeHcoinReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketMcoinExchangeHcoinRsp;
|
import emu.grasscutter.server.packet.send.PacketMcoinExchangeHcoinRsp;
|
||||||
|
|
||||||
@ -15,13 +16,13 @@ public class HandlerMcoinExchangeHcoinReq extends PacketHandler {
|
|||||||
McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq exchangeReq = McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq.parseFrom(payload);
|
McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq exchangeReq = McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq.parseFrom(payload);
|
||||||
|
|
||||||
if (session.getPlayer().getCrystals() < exchangeReq.getMCoinNum() && exchangeReq.getMCoinNum() == exchangeReq.getHCoinNum()) {
|
if (session.getPlayer().getCrystals() < exchangeReq.getMCoinNum() && exchangeReq.getMCoinNum() == exchangeReq.getHCoinNum()) {
|
||||||
|
session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_UNKNOWN_ERROR_VALUE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMCoinNum());
|
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMCoinNum());
|
||||||
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHCoinNum());
|
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHCoinNum());
|
||||||
session.getPlayer().save();
|
session.getPlayer().save();
|
||||||
|
session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE));
|
||||||
session.send(new PacketMcoinExchangeHcoinRsp(session.getPlayer().getCrystals(), session.getPlayer().getPrimogems()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,17 @@ import emu.grasscutter.net.packet.PacketOpcodes;
|
|||||||
|
|
||||||
public class PacketGetGachaInfoRsp extends BasePacket {
|
public class PacketGetGachaInfoRsp extends BasePacket {
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public PacketGetGachaInfoRsp(GachaManager manager) {
|
public PacketGetGachaInfoRsp(GachaManager manager) {
|
||||||
super(PacketOpcodes.GetGachaInfoRsp);
|
super(PacketOpcodes.GetGachaInfoRsp);
|
||||||
|
|
||||||
this.setData(manager.toProto());
|
this.setData(manager.toProto());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketGetGachaInfoRsp(GachaManager manager, String sessionKey) {
|
||||||
|
super(PacketOpcodes.GetGachaInfoRsp);
|
||||||
|
|
||||||
|
this.setData(manager.toProto(sessionKey));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,18 @@ import emu.grasscutter.net.packet.BasePacket;
|
|||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.GetShopmallDataRspOuterClass.GetShopmallDataRsp;
|
import emu.grasscutter.net.proto.GetShopmallDataRspOuterClass.GetShopmallDataRsp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PacketGetShopmallDataRsp extends BasePacket {
|
public class PacketGetShopmallDataRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketGetShopmallDataRsp() {
|
public PacketGetShopmallDataRsp() {
|
||||||
super(PacketOpcodes.GetShopmallDataRsp);
|
super(PacketOpcodes.GetShopmallDataRsp);
|
||||||
|
|
||||||
GetShopmallDataRsp proto = GetShopmallDataRsp.newBuilder().build();
|
List<Integer> shop_malls = List.of(900, 1052, 902, 1001, 903);
|
||||||
|
|
||||||
|
GetShopmallDataRsp proto = GetShopmallDataRsp.newBuilder()
|
||||||
|
.addAllShopTypeList(shop_malls)
|
||||||
|
.build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ import emu.grasscutter.net.proto.McoinExchangeHcoinRspOuterClass;
|
|||||||
|
|
||||||
public class PacketMcoinExchangeHcoinRsp extends BasePacket {
|
public class PacketMcoinExchangeHcoinRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketMcoinExchangeHcoinRsp(int mcoin, int hcoin) {
|
public PacketMcoinExchangeHcoinRsp(int retCode) {
|
||||||
super(PacketOpcodes.McoinExchangeHcoinRsp);
|
super(PacketOpcodes.McoinExchangeHcoinRsp);
|
||||||
|
|
||||||
McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp mcoinExchangeHcoinRsp = McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp.newBuilder()
|
McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp proto = McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp.newBuilder()
|
||||||
.setMCoinNum(mcoin)
|
.setRetcode(retCode)
|
||||||
.setHCoinNum(hcoin).build();
|
.build();
|
||||||
|
|
||||||
this.setData(mcoinExchangeHcoinRsp);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user