12 Commits

Author SHA1 Message Date
d33b699bc0 Merge remote-tracking branch 'origin/pr1' into pr1 2024-06-07 09:40:35 +08:00
85001441a2 A
:
check account state before getPlayer
2024-06-07 09:38:25 +08:00
5e4b98bff1 check account state before getPlayer 2024-06-06 10:18:24 +08:00
76fd5b2e9c Update README_ja-JP.md (#2516) 2024-06-05 21:14:11 -04:00
4022267888 Configuration Update - Shown Email (#2509)
* This version will allow the private server owner to show a different email then "@grasscutter.io" if they want.

* Update src/main/java/emu/grasscutter/config/ConfigContainer.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/game/Account.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/game/Account.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2024-05-13 21:58:46 -04:00
f1f5b54939 (fix:docker) Fix uploading to container registry 2024-03-16 23:09:40 -07:00
f871f261e1 Add Docker Support (#2486)
* chore(docker): add build workflow

* chore(docker): update gradle image

* chore(docker): this really shouldnt be running on raspberry pi's right now.

* chore(docker): not sure why we need unzip here

* chore(docker): attempt to add nodejs to allow the handbook to build

* chore(docker): whoops, needs to be done during build

* chore(docker): i dont know if this is going to work

* chore(docker): replace my username with repo org as I am no longer testing this

* chore(docker): version will change in the future, so fix it now.
2024-03-17 01:57:39 -04:00
eeaccf32c4 add some client download link and fix readme (#2475)
* Update README.md

* Update README_zh-CN.md

* Update README_hn-IN.md
2024-03-17 01:14:10 -04:00
6e1913aacb Add documentation on 404 error page. (#2463)
* Update HttpServer.java

* Update HttpServer.java

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2024-01-18 23:30:03 -05:00
9e17e4aacb Update client link (#2470) 2024-01-18 23:15:13 -05:00
770a793c69 Format code [skip actions] 2023-12-14 05:36:30 +00:00
c4402cc287 Fix some more dungeons (#2449)
* Monds weapon mats domain: Fix time between kill not refreshing
* Inaz husk domain: Fix broken domain challenge
    * `EVENT_ANY_MONSTER_LIVE` is likely sent on tick, not on create. See scene40801_group240801001.lua:
        1. `condition_EVENT_ANY_MONSTER_LIVE_1023` checks for mob 1008 to spawn AND for variable `challenge` to be 1
        2. Mob 1008 spawns during `action_EVENT_SELECT_OPTION_1003`, at `ScriptLib.AddExtraGroupSuite(context, 240801001, 2)`
        3. This spawn triggers `EVENT_ANY_MONSTER_LIVE` for mob 1008 but still fails the condition because `challenge` is still 0.
        4. `challenge` is set to 1 at the end of `action_EVENT_SELECT_OPTION_1003`. By now, `EVENT_ANY_MONSTER_LIVE` for mob 1008 no longer fires, causing the domain challenge to fail to start.
2023-12-14 00:34:50 -05:00
17 changed files with 173 additions and 35 deletions

51
.github/workflows/build_container.yml vendored Normal file
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
.gitignore vendored
View File

@ -64,6 +64,7 @@ tmp/
/*.jar /*.jar
/*.sh /*.sh
!entrypoint.sh
GM Handbook*.txt GM Handbook*.txt
handbook.html handbook.html

38
Dockerfile Normal file
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

View File

@ -24,9 +24,11 @@
### Quick Start (automatic) ### 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 [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. - 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. - 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 small button next to launch.
- Click the launch button. - 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 ### Building

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> <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). **ध्यान:** हम हमेशा परियोजना में योगदानकर्ताओं का स्वागत करते हैं।. अपना योगदान जोड़ने से पहले कृपया हमारा ध्यानपूर्वक पढ़ें [आचार संहिता](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) और सपोर्ट चैनल पर जाएं.

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> <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)をよくお読みください。 **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) を用意する - [Java (バージョン17以降)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) を用意する
- [MongoDB Community Server](https://www.mongodb.com/try/download/community) を用意する - [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](https://github.com/Grasscutters/Cultivation/releases/latest)をダウンロードする。`.msi`インストーラを使ってください。
- 管理者権限を付与して Cultivation を実行した後、右上端にあるダウンロードアイコンのボタンを押す。 - 管理者権限を付与して Cultivation を実行した後、右上端にあるダウンロードアイコンのボタンを押す。
- `Download All-in-One` をクリックする - `Download All-in-One` をクリックする
@ -35,10 +35,9 @@
- `Game Install Path` にゲームファイルのパスを指定する。 - `Game Install Path` にゲームファイルのパスを指定する。
- `Custom Java Path` に、自分が用意したJavaのパスを指定する。 (例: `C:\Program Files\Java\jdk-17\bin\java.exe`) - `Custom Java Path` に、自分が用意したJavaのパスを指定する。 (例: `C:\Program Files\Java\jdk-17\bin\java.exe`)
- その他の設定には手を付けず次の段階に進む。 - その他の設定には手を付けず次の段階に進む。
- Launch の隣にある小さいボタンを押す。 - Launch の隣にある小さいボタンを押す。
- Launchボタンを押す - Launchボタンを押す
- 好きなユーザ名でログインする。パスワードは特段気にすることはない。 - 好きなユーザ名でログインする。ログインに関する設定がデフォルトの場合、パスワードは何を入れてもいい。
### ビルド ### ビルド
@ -79,7 +78,22 @@ chmod +x gradlew
./gradlew jar # コンパイル ./gradlew jar # コンパイル
``` ```
生成されたjarファイルはプロジェクトフォルダのルートにあります。 ##### 手動によるハンドブックの生成
Gradleを使用する場合:
```shell
./gradlew generateHandbook
```
NPMを使用する場合:
```shell
cd src/handbook
npm install
npm run build
```
生成されたjarファイルはプロジェクトのルートフォルダにあります。
### トラブルシューティング ### トラブルシューティング

View File

@ -26,7 +26,9 @@
- 获取Java 17https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html - 获取Java 17https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
- 获取[MongoDB社区版](https://www.mongodb.com/try/download/community) - 获取[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版本](https://github.com/Grasscutters/Cultivation/releases/latest)(使用以“.msi”为后缀的安装包
- 以管理员身份打开Cultivation按右上角的下载按钮。 - 以管理员身份打开Cultivation按右上角的下载按钮。

3
entrypoint.sh Normal file
View File

@ -0,0 +1,3 @@
#/bin/sh
java -jar /app/grasscutter.jar

View File

@ -140,6 +140,7 @@ public class ConfigContainer {
public boolean autoCreate = false; public boolean autoCreate = false;
public boolean EXPERIMENTAL_RealPassword = false; public boolean EXPERIMENTAL_RealPassword = false;
public String[] defaultPermissions = {}; public String[] defaultPermissions = {};
public String playerEmail = "grasscutter.io";
public int maxPlayer = -1; public int maxPlayer = -1;
} }

View File

@ -109,7 +109,7 @@ public class Account {
return email; return email;
} else { } else {
// As of game version 3.5+, only the email is displayed to a user. // 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("*"); this.addPermission("*");
} }
// Set account default language as server default language // Set account default language to server default language
if (!document.containsKey("locale")) { if (!document.containsKey("locale")) {
this.locale = LANGUAGE; this.locale = LANGUAGE;
} }

View File

@ -29,7 +29,7 @@ public class WorldChallenge {
private final AtomicInteger score; private final AtomicInteger score;
private boolean progress; private boolean progress;
private boolean success; private boolean success;
private long startedAt; private int startedAt;
private int finishedTime; private int finishedTime;
/** /**

View File

@ -36,6 +36,6 @@ public class KillMonsterCountInTimeIncChallengeFactoryHandler implements Challen
List.of( List.of(
new KillMonsterCountTrigger(), new KillMonsterCountTrigger(),
new InTimeTrigger(), new InTimeTrigger(),
new KillMonsterTimeIncTrigger(timeInc))); new KillMonsterTimeIncTrigger(timeLimit, timeInc)));
} }
} }

View File

@ -1,11 +1,12 @@
package emu.grasscutter.game.dungeons.challenge.factory; 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.WorldChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType; import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.*; import emu.grasscutter.game.dungeons.challenge.trigger.*;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup; import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List; import java.util.*;
import lombok.val; import lombok.val;
public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryHandler { public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryHandler {
@ -28,6 +29,16 @@ public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryH
Scene scene, Scene scene,
SceneGroup group) { SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId); 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( return new WorldChallenge(
scene, scene,
realGroup, realGroup,
@ -36,6 +47,6 @@ public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryH
List.of(targetCount, timeLimit), List.of(targetCount, timeLimit),
timeLimit, // Limit timeLimit, // Limit
targetCount, // Goal targetCount, // Goal
List.of(new KillMonsterCountTrigger(), new InTimeTrigger())); challengeTriggers);
} }
} }

View File

@ -6,22 +6,33 @@ import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
public class KillMonsterTimeIncTrigger extends ChallengeTrigger { 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; this.increment = increment;
} }
@Override @Override
public void onBegin(WorldChallenge challenge) { public void onBegin(WorldChallenge challenge) {}
// challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 0,
// challenge.getScore().get()));
}
@Override @Override
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) { 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); challenge.setTimeLimit(challenge.getTimeLimit() + increment);
scene.broadcastPacket(
new PacketChallengeDataNotify(
challenge, 2, timeLeft + increment + scene.getSceneTimeSeconds()));
} }
} }

View File

@ -222,7 +222,9 @@ public class EntityMonster extends GameEntity {
} }
@Override @Override
public void onCreate() { public void onTick(int sceneTime) {
super.onTick(sceneTime);
// Lua event // Lua event
getScene() getScene()
.getScriptManager() .getScriptManager()

View File

@ -218,6 +218,8 @@ public final class HttpServer {
<body> <body>
<img src="https://http.cat/404" /> <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> </body>
</html> </html>
"""); """);

View File

@ -42,6 +42,15 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Set account // Set account
session.setAccount(account); session.setAccount(account);
// Checks if the player is banned
if (session.getAccount().isBanned()) {
session.setState(SessionState.ACCOUNT_BANNED);
session.send(
new PacketGetPlayerTokenRsp(
session, 21, "FORBID_CHEATING_PLUGINS", session.getAccount().getBanEndTime()));
return;
}
// Check if player object exists in server // Check if player object exists in server
// NOTE: CHECKING MUST SITUATED HERE (BEFORE getPlayerByUid)! because to save firstly ,to load // NOTE: CHECKING MUST SITUATED HERE (BEFORE getPlayerByUid)! because to save firstly ,to load
// secondly !!! // secondly !!!
@ -93,15 +102,6 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Set player object for session // Set player object for session
session.setPlayer(player); session.setPlayer(player);
// Checks if the player is banned
if (session.getAccount().isBanned()) {
session.setState(SessionState.ACCOUNT_BANNED);
session.send(
new PacketGetPlayerTokenRsp(
session, 21, "FORBID_CHEATING_PLUGINS", session.getAccount().getBanEndTime()));
return;
}
// Load player from database // Load player from database
player.loadFromDatabase(); player.loadFromDatabase();