Compare commits

..

19 Commits

22 changed files with 329 additions and 70 deletions
+51
View File
@@ -0,0 +1,51 @@
name: Build Docker Container
on:
push:
release:
types: [published]
workflow_dispatch: ~
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout Project
uses: actions/checkout@v4
- name: Generate Docker Meta
uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3.1.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Docker image
uses: docker/build-push-action@v5.2.0
with:
context: .
push: true
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+1
View File
@@ -64,6 +64,7 @@ tmp/
/*.jar
/*.sh
!entrypoint.sh
GM Handbook*.txt
handbook.html
+38
View File
@@ -0,0 +1,38 @@
# Builder
FROM gradle:jdk17-alpine as builder
RUN apk add --update nodejs npm
WORKDIR /app
COPY ./ /app/
RUN gradle jar --no-daemon
# Fetch Data
FROM bitnami/git:2.43.0-debian-11-r1 as data
ARG DATA_REPOSITORY=https://gitlab.com/YuukiPS/GC-Resources.git
ARG DATA_BRANCH=4.0
WORKDIR /app
RUN git clone --branch ${DATA_BRANCH} --depth 1 ${DATA_REPOSITORY}
# Result Container
FROM amazoncorretto:17-alpine
WORKDIR /app
# Copy built assets
COPY --from=builder /app/grasscutter-*.jar /app/grasscutter.jar
COPY --from=builder /app/keystore.p12 /app/keystore.p12
# Copy the resources
COPY --from=data /app/GC-Resources/Resources /app/resources/
# Copy startup files
COPY ./entrypoint.sh /app/
CMD [ "sh", "/app/entrypoint.sh" ]
EXPOSE 80 443 8888 22102
+5 -3
View File
@@ -24,9 +24,11 @@
### Quick Start (automatic)
- Get Java 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
- Get [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
- Get [MongoDB Community Server](https://www.mongodb.com/try/download/community)
- Get game version REL4.0.x (4.0.x client can be found here if you don't have it): https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/4.0.0.md
- Get game version REL4.0.x (If you don't have a 4.0.x client, you can find it here and open any of the links to download it):
[4.0.x Client-github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md)
[4.0.x Client-cloud drive](https://www.123pan.com/s/HoqUVv-U7SBA.html)
- Download the [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). Use the `.msi` installer.
- After opening Cultivation (as admin), press the download button in the upper right corner.
@@ -38,7 +40,7 @@
- Click the small button next to launch.
- Click the launch button.
- Log in with whatever username you want. Password doesn't matter.
- Log in with whatever username you want. Password can be anything.
### Building
+2 -2
View File
@@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](README.md) | [简中](docs/README_zh-CN.md) | [繁中](docs/README_zh-TW.md) | [FR](docs/README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**ध्यान:** हम हमेशा परियोजना में योगदानकर्ताओं का स्वागत करते हैं।. अपना योगदान जोड़ने से पहले कृपया हमारा ध्यानपूर्वक पढ़ें [आचार संहिता](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
@@ -75,4 +75,4 @@ chmod +x gradlew
### समस्या निवारण
सामान्य मुद्दों और समाधानों की सूची और सहायता मांगने के लिए कृपया शामिल हों [our Discord server](https://discord.gg/T5vZU6UyeG) और सपोर्ट चैनल पर जाएं.
सामान्य मुद्दों और समाधानों की सूची और सहायता मांगने के लिए कृपया शामिल हों [our Discord server](https://discord.gg/T5vZU6UyeG) और सपोर्ट चैनल पर जाएं.
+19 -5
View File
@@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](README.md) | [简中](docs/README_zh-CN.md) | [繁中](docs/README_zh-TW.md) | [FR](docs/README_fr-FR.md) | [ES](docs/README_es-ES.md) | [HE](docs/README_HE.md) | [RU](docs/README_ru-RU.md) | [PL](docs/README_pl-PL.md) | [ID](docs/README_id-ID.md) | [KR](docs/README_ko-KR.md) | [FIL/PH](docs/README_fil-PH.md) | [NL](docs/README_NL.md) | [JP](docs/README_ja-JP.md) | [IT](docs/README_it-IT.md) | [VI](docs/README_vi-VN.md)
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [HI](README_hn-IN.md)
**Attention:** 私たちはプロジェクトへのコントリビュータをいつでも歓迎します。コントリビュートする前に、私たちの [行動規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)をよくお読みください。
@@ -27,7 +27,7 @@
- [Java (バージョン17以降)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) を用意する
- [MongoDB Community Server](https://www.mongodb.com/try/download/community) を用意する
- ゲームバージョンがREL4.0.Xのものを用意する (4.0.Xのクライアントを持っていない場合は右のリンクからダウンロード): https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/4.0.0.md
- ゲームバージョンがREL4.0.Xのクライアントを用意する (4.0.Xのクライアントを持っていない場合は右のリンクからダウンロード): [Github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md), [クラウド(123云盘)](https://www.123pan.com/s/HoqUVv-U7SBA.html)
- [最新の Cultivation](https://github.com/Grasscutters/Cultivation/releases/latest)をダウンロードする。`.msi`インストーラを使ってください。
- 管理者権限を付与して Cultivation を実行した後、右上端にあるダウンロードアイコンのボタンを押す。
- `Download All-in-One` をクリックする
@@ -35,10 +35,9 @@
- `Game Install Path` にゲームファイルのパスを指定する。
- `Custom Java Path` に、自分が用意したJavaのパスを指定する。 (例: `C:\Program Files\Java\jdk-17\bin\java.exe`)
- その他の設定には手を付けず次の段階に進む。
- Launch の隣にある小さいボタンを押す。
- Launchボタンを押す
- 好きなユーザ名でログインする。パスワードは特段気にすることはない。
- 好きなユーザ名でログインする。ログインに関する設定がデフォルトの場合、パスワードは何を入れてもいい。
### ビルド
@@ -79,7 +78,22 @@ chmod +x gradlew
./gradlew jar # コンパイル
```
生成されたjarファイルはプロジェクトフォルダのルートにあります。
##### 手動によるハンドブックの生成
Gradleを使用する場合:
```shell
./gradlew generateHandbook
```
NPMを使用する場合:
```shell
cd src/handbook
npm install
npm run build
```
生成されたjarファイルはプロジェクトのルートフォルダにあります。
### トラブルシューティング
+3 -1
View File
@@ -26,7 +26,9 @@
- 获取Java 17https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
- 获取[MongoDB社区版](https://www.mongodb.com/try/download/community)
- 获取游戏4.0正式版 (如果你没有4.0的客户端,可以在这里找到):https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/4.0.0.md)
- 获取游戏4.0正式版 (如果你没有4.0的客户端,可以在这里找到):
[123pan share](https://www.123pan.com/s/HoqUVv-U7SBA.html)
[github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md)
- 下载[最新的Cultivation版本](https://github.com/Grasscutters/Cultivation/releases/latest)(使用以“.msi”为后缀的安装包)。
- 以管理员身份打开Cultivation,按右上角的下载按钮。
+3
View File
@@ -0,0 +1,3 @@
#/bin/sh
java -jar /app/grasscutter.jar
@@ -3,8 +3,7 @@ package emu.grasscutter;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.utils.Utils;
import emu.grasscutter.utils.objects.SparseSet;
import java.util.Arrays;
import java.util.*;
public final class GameConstants {
public static String VERSION = "4.0.0";
@@ -60,4 +59,23 @@ public final class GameConstants {
public static final int[] DEFAULT_ABILITY_HASHES =
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
public static final Map<Integer, Integer> YAE_MIKO_ITEM_TO_REGION_COMBINE_BONUS = new HashMap<>() {{
put(104304, 1);
put(104307, 1);
put(104310, 2);
put(104313, 2);
put(104316, 2);
put(104320, 3);
put(104323, 3);
put(104326, 3);
put(104329, 4);
put(104332, 4);
put(104335, 4);
}};
public static final Map<Integer, List<Integer>> YAE_MIKO_REGION_TO_ITEM_COMBINE_BONUS = new HashMap<>() {{
put(1, List.of(104304, 104307));
put(2, List.of(104310, 104313, 104316));
put(3, List.of(104320, 104323, 104326));
put(4, List.of(104329, 104332, 104335));
}};
}
@@ -17,8 +17,10 @@ public final class StopCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
CommandHandler.sendMessage(null, translate("commands.stop.success"));
for (Player p : Grasscutter.getGameServer().getPlayers().values()) {
CommandHandler.sendMessage(p, translate(p, "commands.stop.success"));
if (Grasscutter.getGameServer() != null) {
for (Player p : Grasscutter.getGameServer().getPlayers().values()) {
CommandHandler.sendMessage(p, translate(p, "commands.stop.success"));
}
}
System.exit(1000);
@@ -140,6 +140,7 @@ public class ConfigContainer {
public boolean autoCreate = false;
public boolean EXPERIMENTAL_RealPassword = false;
public String[] defaultPermissions = {};
public String playerEmail = "grasscutter.io";
public int maxPlayer = -1;
}
@@ -109,7 +109,7 @@ public class Account {
return email;
} else {
// As of game version 3.5+, only the email is displayed to a user.
return this.getUsername() + "@grasscutter.io";
return this.getUsername() + "@" + ACCOUNT.playerEmail;
}
}
@@ -235,7 +235,7 @@ public class Account {
this.addPermission("*");
}
// Set account default language as server default language
// Set account default language to server default language
if (!document.containsKey("locale")) {
this.locale = LANGUAGE;
}
@@ -0,0 +1,19 @@
package emu.grasscutter.game.combine;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class CombineBonusData {
private int avatarId;
private int combineType;
private BonusType bonusType;
private List<Double> paramVec;
public enum BonusType {
COMBINE_BONUS_DOUBLE,
COMBINE_BONUS_REFUND,
COMBINE_BONUS_REFUND_RANDOM,
}
}
@@ -1,9 +1,11 @@
package emu.grasscutter.game.combine;
import emu.grasscutter.GameConstants;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.CombineData;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
@@ -12,15 +14,26 @@ import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import emu.grasscutter.server.game.*;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Utils;
import io.netty.util.internal.ThreadLocalRandom;
import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
public class CombineManger extends BaseGameSystem {
private static final Int2ObjectMap<List<Integer>> reliquaryDecomposeData =
new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<CombineBonusData> combineBonusData = new Int2ObjectOpenHashMap<>();
public CombineManger(GameServer server) {
super(server);
// load combine bonus data
try {
DataLoader.loadList("CombineBonus.json", CombineBonusData.class)
.forEach(entry -> combineBonusData.put(entry.getAvatarId(), entry));
} catch (Exception ignored) {
Grasscutter.getLogger()
.error("Unable to load combine bonus data. Please place CombineBonus.json in the data folder.");
}
}
public static void initialize() {
@@ -47,7 +60,7 @@ public class CombineManger extends BaseGameSystem {
return true;
}
public CombineResult combineItem(Player player, int cid, int count) {
public CombineResult combineItem(Player player, int cid, int count, long avatarGuid) {
// check config exist
if (!GameData.getCombineDataMap().containsKey(cid)) {
player.getWorld().getHost().sendPacket(new PacketCombineRsp());
@@ -81,11 +94,104 @@ public class CombineManger extends BaseGameSystem {
result.setMaterial(List.of());
result.setResult(
List.of(
new ItemParamData(
combineData.getResultItemId(), combineData.getResultItemCount() * count)));
// TODO lucky characters
result.setExtra(List.of());
result.setBack(List.of());
new ItemParamData(combineData.getResultItemId(), combineData.getResultItemCount())));
// lucky characters
int luckyCount = 0;
Avatar avatar = player.getAvatars().getAvatarByGuid(avatarGuid);
CombineBonusData combineBonusAvatar = combineBonusData.get(avatar.getAvatarId());
if (combineBonusAvatar != null
&& combineData.getCombineType() == combineBonusAvatar.getCombineType()) {
double luckyChange = combineBonusAvatar.getParamVec().get(0);
for (int i = 0; i < count; i++) {
if (ThreadLocalRandom.current().nextDouble() <= luckyChange) {
luckyCount++;
}
}
}
result.setExtra(new ArrayList<ItemParamData>());
result.setBack(new ArrayList<ItemParamData>());
result.setRandom(new ArrayList<ItemParamData>());
// add lucky items
if (luckyCount > 0) {
switch (combineBonusAvatar.getBonusType()) {
case COMBINE_BONUS_DOUBLE -> {
var combineExtra = new ItemParamData(combineData.getResultItemId(), luckyCount);
player.getInventory().addItem(combineExtra);
result.getExtra().add(combineExtra);
}
case COMBINE_BONUS_REFUND -> {
if (combineData.getMaterialItems().size() == 1) {
var combineBack = new ItemParamData(combineData.getMaterialItems().get(0).getItemId(),
luckyCount);
player.getInventory().addItem(combineBack);
result.getBack().add(combineBack);
} else {
Map<Integer, Integer> mapIdCount = new HashMap<>();
for (int i = 0; i < luckyCount; i++) {
var randomId = combineData
.getMaterialItems()
.get(
ThreadLocalRandom.current()
.nextInt(combineData.getMaterialItems().size()))
.getItemId();
mapIdCount.put(randomId, mapIdCount.getOrDefault(randomId, 0) + 1);
}
for (var entry : mapIdCount.entrySet()) {
var combineBack = new ItemParamData(entry.getKey(), entry.getValue());
player.getInventory().addItem(combineBack);
result.getBack().add(combineBack);
}
}
}
case COMBINE_BONUS_REFUND_RANDOM -> {
// for yae miko, "Has a 25% chance to get 1 regional Character Talent Material
// (base
// material excluded) when crafting. The rarity is that of the base material."
// from wiki
// map of material id to region id
Map<Integer, Integer> itemToRegion = GameConstants.YAE_MIKO_ITEM_TO_REGION_COMBINE_BONUS;
// get list of material id with every region
Map<Integer, List<Integer>> regionToId = GameConstants.YAE_MIKO_REGION_TO_ITEM_COMBINE_BONUS;
// check material id in itemToRegion
int itemId = combineData.getMaterialItems().get(0).getItemId();
int rank = 0; // rank of material
if (itemToRegion.get(itemId) != null)
rank = 1;
if (itemToRegion.get(itemId - 1) != null) {
rank = 2;
itemId -= 1;
}
if (rank >= 1) { // if material is regional
// get list of material id with same region
List<Integer> listIdRandom = regionToId.get(itemToRegion.get(itemId));
// remove material id from array
listIdRandom.remove(Integer.valueOf(itemId));
HashMap<Integer, Integer> mapIdCount = new HashMap<>();
// pick random material from list with luckyCount
for (int i = 0; i < luckyCount; i++) {
int randomId = listIdRandom.get(ThreadLocalRandom.current().nextInt(listIdRandom.size()));
mapIdCount.put(randomId, mapIdCount.getOrDefault(randomId, 0) + 1);
}
// add to random list
for (var entry : mapIdCount.entrySet()) {
// if rank 2, add 1 to material id
var combineRandom = new ItemParamData(
(rank == 2) ? entry.getKey() + 1 : entry.getKey(), entry.getValue());
player.getInventory().addItem(combineRandom);
result.getRandom().add(combineRandom);
}
}
}
}
}
return result;
}
@@ -2,42 +2,14 @@ package emu.grasscutter.game.combine;
import emu.grasscutter.data.common.ItemParamData;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Setter @Getter
public class CombineResult {
private List<ItemParamData> material;
private List<ItemParamData> result;
private List<ItemParamData> extra;
private List<ItemParamData> back;
public List<ItemParamData> getMaterial() {
return material;
}
public void setMaterial(List<ItemParamData> material) {
this.material = material;
}
public List<ItemParamData> getResult() {
return result;
}
public void setResult(List<ItemParamData> result) {
this.result = result;
}
public List<ItemParamData> getExtra() {
return extra;
}
public void setExtra(List<ItemParamData> extra) {
this.extra = extra;
}
public List<ItemParamData> getBack() {
return back;
}
public void setBack(List<ItemParamData> back) {
this.back = back;
}
private List<ItemParamData> random;
}
@@ -29,7 +29,7 @@ public class WorldChallenge {
private final AtomicInteger score;
private boolean progress;
private boolean success;
private long startedAt;
private int startedAt;
private int finishedTime;
/**
@@ -36,6 +36,6 @@ public class KillMonsterCountInTimeIncChallengeFactoryHandler implements Challen
List.of(
new KillMonsterCountTrigger(),
new InTimeTrigger(),
new KillMonsterTimeIncTrigger(timeInc)));
new KillMonsterTimeIncTrigger(timeLimit, timeInc)));
}
}
@@ -1,11 +1,12 @@
package emu.grasscutter.game.dungeons.challenge.factory;
import emu.grasscutter.data.GameData;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.*;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import java.util.*;
import lombok.val;
public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryHandler {
@@ -28,6 +29,16 @@ public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryH
Scene scene,
SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId);
val challengeTriggers = new ArrayList<ChallengeTrigger>();
challengeTriggers.addAll(List.of(new KillMonsterCountTrigger(), new InTimeTrigger()));
val challengeData = GameData.getDungeonChallengeConfigDataMap().get(challengeId);
val challengeType = challengeData.getChallengeType();
if (challengeType == ChallengeType.CHALLENGE_KILL_COUNT_FAST) {
challengeTriggers.add(
new KillMonsterTimeIncTrigger(timeLimit, 0 /* refresh to original limit on kill */));
}
return new WorldChallenge(
scene,
realGroup,
@@ -36,6 +47,6 @@ public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryH
List.of(targetCount, timeLimit),
timeLimit, // Limit
targetCount, // Goal
List.of(new KillMonsterCountTrigger(), new InTimeTrigger()));
challengeTriggers);
}
}
@@ -6,22 +6,33 @@ import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
public class KillMonsterTimeIncTrigger extends ChallengeTrigger {
private int increment;
private final int maxTime;
private final int increment;
public KillMonsterTimeIncTrigger(int increment) {
public KillMonsterTimeIncTrigger(int maxTime, int increment) {
this.maxTime = maxTime;
this.increment = increment;
}
@Override
public void onBegin(WorldChallenge challenge) {
// challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 0,
// challenge.getScore().get()));
}
public void onBegin(WorldChallenge challenge) {}
@Override
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) {
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 0, increment));
var scene = challenge.getScene();
var elapsed = scene.getSceneTimeSeconds() - challenge.getStartedAt();
var timeLeft = challenge.getTimeLimit() - elapsed;
var increment = this.increment;
if (increment == 0) {
// Refresh time limit back to max
increment = maxTime - timeLeft;
} else if (maxTime < timeLeft + increment) {
// Don't add back more time than original limit
increment -= timeLeft + increment - maxTime;
}
challenge.setTimeLimit(challenge.getTimeLimit() + increment);
scene.broadcastPacket(
new PacketChallengeDataNotify(
challenge, 2, timeLeft + increment + scene.getSceneTimeSeconds()));
}
}
@@ -222,7 +222,9 @@ public class EntityMonster extends GameEntity {
}
@Override
public void onCreate() {
public void onTick(int sceneTime) {
super.onTick(sceneTime);
// Lua event
getScene()
.getScriptManager()
@@ -218,6 +218,8 @@ public final class HttpServer {
<body>
<img src="https://http.cat/404" />
<h1>Grasscutter cannot find the route you're trying to access.</h1>
<p>Your proxy is active, so if you're trying to download something close the game/stop the proxy.</p>
</body>
</html>
""");
@@ -20,7 +20,11 @@ public class HandlerCombineReq extends PacketHandler {
session
.getServer()
.getCombineSystem()
.combineItem(session.getPlayer(), req.getCombineId(), req.getCombineCount());
.combineItem(
session.getPlayer(),
req.getCombineId(),
req.getCombineCount(),
req.getAvatarGuid());
if (result == null) {
return;
@@ -33,7 +37,7 @@ public class HandlerCombineReq extends PacketHandler {
toItemParamList(result.getResult()),
toItemParamList(result.getExtra()),
toItemParamList(result.getBack()),
toItemParamList(result.getBack())));
toItemParamList(result.getRandom())));
}
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<ItemParamData> list) {