├── .gitattributes ├── .github ├── FUNDING.yml ├── crowdin.yml ├── dependabot.yml └── workflows │ ├── build-docker.yml │ ├── build.yml │ └── crowdin-sync.yml ├── .gitignore ├── .idea └── copyright │ ├── GPL_3_0.xml │ └── profiles_settings.xml ├── Dockerfile ├── LICENSE ├── README.md ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ └── groovy │ ├── base.application-conventions.gradle │ ├── base.base-conventions.gradle │ ├── base.exclude-run-folder.gradle │ ├── base.fill-build-constants.gradle │ ├── base.include-in-jar-configuration.gradle │ ├── base.publishing-conventions.gradle │ ├── via.viaversion-maven-publishing.gradle │ └── viaproxy.publishing-conventions.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── net │ └── raphimc │ └── viaproxy │ ├── ViaProxy.java │ ├── cli │ ├── BetterHelpFormatter.java │ ├── ConsoleFormatter.java │ ├── ConsoleHandler.java │ ├── HelpRequestedException.java │ └── command │ │ ├── Command.java │ │ ├── CommandManager.java │ │ ├── executor │ │ ├── CommandExecutor.java │ │ └── ConsoleCommandExecutor.java │ │ └── impl │ │ ├── GcCommand.java │ │ ├── HelpCommand.java │ │ ├── StopCommand.java │ │ ├── ThreadDumpCommand.java │ │ ├── UploadLogCommand.java │ │ └── ViaVersionCommand.java │ ├── injection │ ├── ClassicWorldHeightInjection.java │ ├── TransformerDowngrader.java │ └── mixins │ │ ├── MixinBlockItemPacketRewriter1_20_5.java │ │ ├── MixinBlockItemPacketRewriter1_21_4.java │ │ ├── MixinC2SHandshakingClientIntentionPacket.java │ │ ├── MixinCommonBoss.java │ │ ├── MixinConfigurationState.java │ │ ├── MixinEntityPacketRewriter1_17.java │ │ ├── MixinEntityPacketRewriter1_20_5.java │ │ ├── MixinEntityTracker1_9.java │ │ ├── MixinItemPacketRewriter1_9.java │ │ ├── MixinPluginManager.java │ │ ├── MixinProtocol1_18To1_18_2.java │ │ ├── MixinProtocol1_20To1_20_2.java │ │ ├── MixinViaLegacyConfig.java │ │ ├── MixinWorldPacketRewriter1_16_2.java │ │ └── MixinWorldPacketRewriter1_17.java │ ├── plugins │ ├── PluginManager.java │ ├── ViaProxyPlugin.java │ └── events │ │ ├── Client2ProxyChannelInitializeEvent.java │ │ ├── Client2ProxyHandlerCreationEvent.java │ │ ├── ClientLoggedInEvent.java │ │ ├── ConnectEvent.java │ │ ├── ConsoleCommandEvent.java │ │ ├── FillPlayerDataEvent.java │ │ ├── JoinServerRequestEvent.java │ │ ├── PostOptionsParseEvent.java │ │ ├── PreConnectEvent.java │ │ ├── PreOptionsParseEvent.java │ │ ├── ProtocolTranslatorInitEvent.java │ │ ├── Proxy2ServerChannelInitializeEvent.java │ │ ├── Proxy2ServerHandlerCreationEvent.java │ │ ├── ProxySessionCreationEvent.java │ │ ├── ProxyStartEvent.java │ │ ├── ProxyStopEvent.java │ │ ├── ShouldVerifyOnlineModeEvent.java │ │ ├── ViaLoadingEvent.java │ │ ├── ViaProxyLoadedEvent.java │ │ └── types │ │ ├── EventCancellable.java │ │ └── ITyped.java │ ├── protocoltranslator │ ├── ProtocolTranslator.java │ ├── impl │ │ ├── ViaProxyMappingDataLoader.java │ │ ├── ViaProxyVLLoader.java │ │ ├── ViaProxyVLPipeline.java │ │ ├── ViaProxyViaCodec.java │ │ ├── ViaProxyViaLegacyPlatformImpl.java │ │ └── ViaProxyViaVersionPlatformImpl.java │ ├── providers │ │ ├── ViaProxyClassicCustomCommandProvider.java │ │ ├── ViaProxyClassicMPPassProvider.java │ │ ├── ViaProxyClassicWorldHeightProvider.java │ │ ├── ViaProxyCompressionProvider.java │ │ ├── ViaProxyEncryptionProvider.java │ │ ├── ViaProxyGameProfileFetcher.java │ │ ├── ViaProxyNettyPipelineProvider.java │ │ ├── ViaProxyOldAuthProvider.java │ │ ├── ViaProxyTransferProvider.java │ │ └── ViaProxyVersionProvider.java │ └── viaproxy │ │ ├── ConsoleCommandSender.java │ │ ├── ViaProxyConfig.java │ │ └── loading_terrain_fix │ │ └── SpawnPositionTracker.java │ ├── proxy │ ├── LoginState.java │ ├── client2proxy │ │ ├── Client2ProxyChannelInitializer.java │ │ ├── Client2ProxyHandler.java │ │ ├── HAProxyHandler.java │ │ └── passthrough │ │ │ ├── LegacyPassthroughInitialHandler.java │ │ │ ├── PassthroughClient2ProxyChannelInitializer.java │ │ │ └── PassthroughClient2ProxyHandler.java │ ├── external_interface │ │ ├── AuthLibServices.java │ │ └── ExternalInterface.java │ ├── packethandler │ │ ├── BrandCustomPayloadPacketHandler.java │ │ ├── ChatSignaturePacketHandler.java │ │ ├── CompressionPacketHandler.java │ │ ├── ConfigurationPacketHandler.java │ │ ├── DisconnectPacketHandler.java │ │ ├── LoginPacketHandler.java │ │ ├── PacketHandler.java │ │ ├── ResourcePackPacketHandler.java │ │ ├── ResourcePackSpooferPacketHandler.java │ │ ├── SimpleVoiceChatPacketHandler.java │ │ ├── StatusPacketHandler.java │ │ ├── TransferPacketHandler.java │ │ ├── UnexpectedPacketHandler.java │ │ └── ViaVersionConnectionDetailsPacketHandler.java │ ├── proxy2server │ │ ├── Proxy2ServerChannelInitializer.java │ │ ├── Proxy2ServerHandler.java │ │ └── passthrough │ │ │ ├── PassthroughProxy2ServerChannelInitializer.java │ │ │ └── PassthroughProxy2ServerHandler.java │ ├── session │ │ ├── BedrockProxyConnection.java │ │ ├── DummyProxyConnection.java │ │ ├── LegacyProxyConnection.java │ │ ├── ProxyConnection.java │ │ └── UserOptions.java │ └── util │ │ ├── ChannelUtil.java │ │ ├── CloseAndReturn.java │ │ ├── ExceptionUtil.java │ │ ├── HAProxyUtil.java │ │ ├── ThrowingChannelFutureListener.java │ │ └── TransferDataHolder.java │ ├── saves │ ├── AbstractSave.java │ ├── SaveManager.java │ ├── SaveMigrator.java │ └── impl │ │ ├── AccountsSaveV3.java │ │ ├── UISave.java │ │ └── accounts │ │ ├── Account.java │ │ ├── BedrockAccount.java │ │ ├── ClassicAccount.java │ │ ├── MicrosoftAccount.java │ │ └── OfflineAccount.java │ ├── tasks │ ├── SystemRequirementsCheck.java │ └── UpdateCheckTask.java │ ├── ui │ ├── I18n.java │ ├── SplashScreen.java │ ├── UITab.java │ ├── ViaProxyWindow.java │ ├── elements │ │ └── LinkLabel.java │ ├── events │ │ └── UICloseEvent.java │ ├── impl │ │ ├── AccountsTab.java │ │ ├── AdvancedTab.java │ │ ├── GeneralTab.java │ │ ├── RealmsTab.java │ │ └── UISettingsTab.java │ └── popups │ │ ├── AddAccountPopup.java │ │ └── DownloadPopup.java │ └── util │ ├── AddressUtil.java │ ├── ArrayHelper.java │ ├── ClassLoaderPriorityUtil.java │ ├── JarUtil.java │ ├── ProtocolVersionDetector.java │ ├── ProtocolVersionUtil.java │ ├── Proxy.java │ ├── StringUtil.java │ ├── TFunction.java │ ├── config │ ├── AccountTypeSerializer.java │ ├── ProtocolVersionTypeSerializer.java │ ├── ProxyTypeSerializer.java │ ├── SocketAddressTypeSerializer.java │ └── TargetAddressTypeSerializer.java │ └── logging │ ├── IpRedactor.java │ ├── Logger.java │ └── LoggerPrintStream.java └── resources ├── assets └── viaproxy │ ├── data │ ├── armor-damages-b1.8.1.json │ ├── item-attributes-1.8.json │ ├── item-identifiers-1.8.json │ ├── item-tool-components.json │ └── materials-1.19.4.json │ ├── icons │ └── icon.png │ └── language │ ├── af_ZA.properties │ ├── ar_SA.properties │ ├── ca_ES.properties │ ├── cs_CZ.properties │ ├── da_DK.properties │ ├── de_DE.properties │ ├── el_GR.properties │ ├── en_US.properties │ ├── es_ES.properties │ ├── fi_FI.properties │ ├── fr_FR.properties │ ├── he_IL.properties │ ├── hu_HU.properties │ ├── it_IT.properties │ ├── ja_JP.properties │ ├── ko_KR.properties │ ├── nl_NL.properties │ ├── no_NO.properties │ ├── pl_PL.properties │ ├── pt_BR.properties │ ├── pt_PT.properties │ ├── ro_RO.properties │ ├── ru_RU.properties │ ├── sr_SP.properties │ ├── sv_SE.properties │ ├── tr_TR.properties │ ├── uk_UA.properties │ ├── vi_VN.properties │ ├── zh_CN.properties │ └── zh_TW.properties └── log4j2.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: rk_01 2 | -------------------------------------------------------------------------------- /.github/crowdin.yml: -------------------------------------------------------------------------------- 1 | project_id_env: "CROWDIN_PROJECT_ID" 2 | api_token_env: "CROWDIN_PERSONAL_TOKEN" 3 | base_path: "../" 4 | preserve_hierarchy: true 5 | files: [ 6 | { 7 | source: "/src/main/resources/assets/viaproxy/language/en_US.properties", 8 | translation: "/src/main/resources/assets/viaproxy/language/%locale_with_underscore%.properties", 9 | escape_quotes: 0, 10 | escape_special_characters: 0 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | registries: 3 | maven-central: 4 | type: maven-repository 5 | url: "https://repo.maven.apache.org/maven2/" 6 | updates: 7 | - package-ecosystem: "gradle" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | registries: 12 | - maven-central 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | schedule: 16 | interval: "weekly" 17 | -------------------------------------------------------------------------------- /.github/workflows/build-docker.yml: -------------------------------------------------------------------------------- 1 | name: build-docker 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | 8 | env: 9 | REGISTRY: ghcr.io 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-24.04 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v4 17 | with: 18 | persist-credentials: false 19 | - name: Validate Gradle Wrapper 20 | uses: gradle/actions/wrapper-validation@v4 21 | - name: Set up JDK 21 22 | uses: actions/setup-java@v4 23 | with: 24 | distribution: temurin 25 | java-version: 21 26 | check-latest: true 27 | - name: Build with Gradle 28 | run: ./gradlew build 29 | - name: Set up QEMU 30 | uses: docker/setup-qemu-action@v3 31 | - name: Set up Docker Buildx 32 | uses: docker/setup-buildx-action@v3 33 | - name: Log into registry ${{ env.REGISTRY }} 34 | uses: docker/login-action@v3 35 | with: 36 | registry: ${{ env.REGISTRY }} 37 | username: ${{ github.actor }} 38 | password: ${{ secrets.GITHUB_TOKEN }} 39 | - name: Extract Docker metadata 40 | id: meta 41 | uses: docker/metadata-action@v5 42 | with: 43 | tags: | 44 | type=raw,value=latest 45 | type=raw,value=${{ github.ref_name }} 46 | type=semver,pattern={{version}} 47 | images: ${{ env.REGISTRY }}/${{ github.repository }} 48 | - name: Build and push Docker image 49 | uses: docker/build-push-action@v6 50 | with: 51 | context: . 52 | platforms: linux/amd64,linux/arm64 53 | push: true 54 | provenance: false 55 | tags: ${{ steps.meta.outputs.tags }} 56 | labels: ${{ steps.meta.outputs.labels }} 57 | cache-from: type=gha 58 | cache-to: type=gha,mode=max 59 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, pull_request, workflow_dispatch] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-24.04 7 | if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} 8 | steps: 9 | - name: Checkout Repository 10 | uses: actions/checkout@v4 11 | with: 12 | persist-credentials: false 13 | - name: Validate Gradle Wrapper 14 | uses: gradle/actions/wrapper-validation@v4 15 | - name: Set up JDK 21 16 | uses: actions/setup-java@v4 17 | with: 18 | distribution: temurin 19 | java-version: 21 20 | check-latest: true 21 | - name: Build with Gradle 22 | run: ./gradlew build 23 | - name: Upload Artifacts to GitHub 24 | uses: actions/upload-artifact@v4 25 | with: 26 | name: Artifacts 27 | path: build/libs/ 28 | -------------------------------------------------------------------------------- /.github/workflows/crowdin-sync.yml: -------------------------------------------------------------------------------- 1 | name: crowdin-sync 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | synchronize-with-crowdin: 9 | runs-on: ubuntu-24.04 10 | steps: 11 | - name: Checkout Repository 12 | uses: actions/checkout@v4 13 | with: 14 | persist-credentials: false 15 | - name: Crowdin Sync 16 | uses: crowdin/github-action@v2 17 | with: 18 | config: .github/crowdin.yml 19 | upload_sources: true 20 | download_translations: true 21 | localization_branch_name: l10n_crowdin_translations 22 | create_pull_request: true 23 | pull_request_base_branch_name: main 24 | pull_request_title: "New Crowdin Translations" 25 | pull_request_body: "New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)" 26 | commit_message: "[ci skip] Updated translations from Crowdin" 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} 30 | CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | *.log.gz 7 | 8 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 9 | hs_err_pid* 10 | 11 | # Project files 12 | /.idea/* 13 | !/.idea/copyright/ 14 | /.gradle/ 15 | /buildSrc/.gradle/ 16 | build/ 17 | out/ 18 | /run/ 19 | -------------------------------------------------------------------------------- /.idea/copyright/GPL_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:21-jre-alpine 2 | WORKDIR /app/run 3 | COPY /build/libs/ViaProxy-*.jar /app/ViaProxy.jar 4 | ENTRYPOINT ["java", "-jar", "/app/ViaProxy.jar", "config", "viaproxy.yml"] 5 | -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "groovy-gradle-plugin" 3 | } 4 | 5 | repositories { 6 | gradlePluginPortal() 7 | } 8 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.application-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "application" 3 | id "base.include-in-jar-configuration" 4 | id "base.exclude-run-folder" 5 | } 6 | 7 | jar { 8 | manifest { 9 | attributes( 10 | "Main-Class": application.mainClass, 11 | "Multi-Release": "true", 12 | "Enable-Native-Access": "ALL-UNNAMED" 13 | ) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.base-conventions.gradle: -------------------------------------------------------------------------------- 1 | base { 2 | java.toolchain.languageVersion = JavaLanguageVersion.of(project.java_version) 3 | 4 | group = project.maven_group 5 | archivesName = project.name 6 | version = project.maven_version 7 | } 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | jar { 14 | if (layout.projectDirectory.file("LICENSE").asFile.exists()) { 15 | def projectName = project.name 16 | from(layout.projectDirectory.file("LICENSE")) { 17 | rename { "${it}_${projectName}" } 18 | } 19 | } else if (rootProject.layout.projectDirectory.file("LICENSE").asFile.exists()) { 20 | def projectName = rootProject.name 21 | from(rootProject.layout.projectDirectory.file("LICENSE")) { 22 | rename { "${it}_${projectName}" } 23 | } 24 | } 25 | } 26 | 27 | tasks.withType(JavaCompile).configureEach { 28 | it.options.encoding = "UTF-8" 29 | } 30 | 31 | tasks.withType(Javadoc).configureEach { 32 | it.options.encoding = "UTF-8" 33 | it.options.addStringOption("Xdoclint:none", "-quiet") 34 | } 35 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.exclude-run-folder.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "idea" 3 | } 4 | 5 | idea { 6 | module { 7 | ["run"].each { 8 | excludeDirs << layout.projectDirectory.file("$it").asFile 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.fill-build-constants.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "net.raphimc.class-token-replacer" 3 | } 4 | 5 | sourceSets.configureEach { 6 | it.classTokenReplacer { 7 | property("\${version}", project.version) 8 | property("\${commit_hash}", latestCommitHash().get()) 9 | } 10 | } 11 | 12 | Provider latestCommitHash() { 13 | return providers.exec { 14 | commandLine = ["git", "rev-parse", "--short", "HEAD"] 15 | }.standardOutput.getAsText().map(String::trim) 16 | } 17 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.include-in-jar-configuration.gradle: -------------------------------------------------------------------------------- 1 | configurations { 2 | includeInJar 3 | 4 | implementation.extendsFrom(includeInJar) 5 | api.extendsFrom(includeInJar) 6 | } 7 | 8 | jar { 9 | dependsOn(configurations.includeInJar) 10 | from { 11 | duplicatesStrategy = DuplicatesStrategy.EXCLUDE 12 | configurations.includeInJar.collect { 13 | zipTree(it) 14 | } 15 | } { 16 | exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/base.publishing-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "maven-publish" 3 | id "signing" 4 | } 5 | 6 | java { 7 | withSourcesJar() 8 | withJavadocJar() 9 | } 10 | 11 | publishing { 12 | publications { 13 | mavenJava(MavenPublication) { 14 | from(components.java) 15 | 16 | groupId = project.maven_group 17 | artifactId = project.maven_name 18 | version = project.maven_version 19 | } 20 | } 21 | } 22 | 23 | signing { 24 | setRequired(false) 25 | sign(publishing.publications.mavenJava) 26 | } 27 | 28 | tasks.withType(PublishToMavenRepository).configureEach { 29 | it.dependsOn(tasks.withType(Sign)) 30 | } 31 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/via.viaversion-maven-publishing.gradle: -------------------------------------------------------------------------------- 1 | publishing { 2 | repositories { 3 | maven { 4 | name = "Via" 5 | url = "https://repo.viaversion.com/" 6 | 7 | credentials(PasswordCredentials) 8 | authentication { 9 | basic(BasicAuthentication) 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/viaproxy.publishing-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "base.publishing-conventions" 3 | id "via.viaversion-maven-publishing" 4 | } 5 | 6 | publishing { 7 | publications { 8 | mavenJava { 9 | pom { 10 | name = "ViaProxy" 11 | description = "Standalone proxy which allows players to join EVERY Minecraft server version (Classic, Alpha, Beta, Release, Bedrock)" 12 | url = "https://github.com/ViaVersion/ViaProxy" 13 | licenses { 14 | license { 15 | name = "GPL-3.0 License" 16 | url = "https://github.com/ViaVersion/ViaProxy/blob/main/LICENSE" 17 | } 18 | } 19 | developers { 20 | developer { 21 | id = "RK_01" 22 | } 23 | } 24 | scm { 25 | connection = "scm:git:git://github.com/ViaVersion/ViaProxy.git" 26 | developerConnection = "scm:git:ssh://github.com/ViaVersion/ViaProxy.git" 27 | url = "https://github.com/ViaVersion/ViaProxy.git" 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=true 2 | org.gradle.parallel=true 3 | org.gradle.configuration-cache=true 4 | org.gradle.jvmargs=-Xmx2G 5 | 6 | java_version=17 7 | maven_group=net.raphimc 8 | maven_name=ViaProxy 9 | maven_version=3.4.2-SNAPSHOT 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViaVersion/ViaProxy/126cb71839ac709ad43a20d3e253b5f82c1e5c6c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | plugins { 9 | id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0" 10 | } 11 | 12 | rootProject.name = "ViaProxy" 13 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/BetterHelpFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli; 19 | 20 | import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; 21 | import joptsimple.BuiltinHelpFormatter; 22 | import joptsimple.OptionDescriptor; 23 | import joptsimple.internal.Classes; 24 | import joptsimple.internal.Strings; 25 | 26 | import java.util.List; 27 | 28 | public class BetterHelpFormatter extends BuiltinHelpFormatter { 29 | 30 | public BetterHelpFormatter() { 31 | super(120, 2); 32 | } 33 | 34 | @Override 35 | protected String extractTypeIndicator(OptionDescriptor descriptor) { 36 | String indicator = descriptor.argumentTypeIndicator(); 37 | if (indicator != null) { 38 | indicator = indicator.substring(indicator.indexOf('$') + 1); 39 | if (indicator.startsWith("[")) { 40 | return indicator.substring(1, indicator.length() - 1); 41 | } 42 | } 43 | return !Strings.isNullOrEmpty(indicator) && !String.class.getName().equals(indicator) ? Classes.shortNameOf(indicator) : "String"; 44 | } 45 | 46 | @Override 47 | protected String createDefaultValuesDisplay(List defaultValues) { 48 | if (defaultValues.size() == 1) { 49 | Object value = defaultValues.get(0); 50 | if (value instanceof ProtocolVersion version) { 51 | return version.getName(); 52 | } else if (value instanceof String) { 53 | return "\"" + value + "\""; 54 | } 55 | 56 | return value.toString(); 57 | } 58 | 59 | return defaultValues.toString(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/ConsoleHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli; 19 | 20 | import net.raphimc.viaproxy.cli.command.CommandManager; 21 | import net.raphimc.viaproxy.util.logging.Logger; 22 | 23 | import java.io.IOException; 24 | import java.util.Scanner; 25 | 26 | public class ConsoleHandler { 27 | 28 | public static void hookConsole() { 29 | try { // Best way I could find to check if a console is attached to System.in 30 | System.in.available(); 31 | } catch (IOException e) { 32 | Logger.LOGGER.info("Console input is not available. CLI commands are disabled."); 33 | return; 34 | } 35 | 36 | new Thread(ConsoleHandler::listen, "Console-Handler").start(); 37 | } 38 | 39 | private static void listen() { 40 | final CommandManager commandManager = new CommandManager(); 41 | final Scanner scanner = new Scanner(System.in); 42 | try { 43 | while (scanner.hasNextLine()) { 44 | final String line = scanner.nextLine(); 45 | try { 46 | commandManager.execute(line); 47 | } catch (Throwable e) { 48 | Logger.LOGGER.error("Error while handling console input", e); 49 | } 50 | } 51 | } catch (Throwable e) { 52 | Logger.LOGGER.error("Error while reading console input", e); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/HelpRequestedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli; 19 | 20 | public class HelpRequestedException extends RuntimeException { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command; 19 | 20 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 21 | import net.lenni0451.commons.brigadier.CommandBuilder; 22 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 23 | 24 | public abstract class Command implements CommandBuilder { 25 | 26 | private final String[] names; 27 | private final String description; 28 | private final String help; 29 | 30 | public Command(final String name, final String description, final String help, final String... aliases) { 31 | this.names = new String[aliases.length + 1]; 32 | this.names[0] = name; 33 | System.arraycopy(aliases, 0, this.names, 1, aliases.length); 34 | this.description = description; 35 | this.help = help; 36 | } 37 | 38 | public abstract void register(final LiteralArgumentBuilder builder); 39 | 40 | public String getName() { 41 | return this.names[0]; 42 | } 43 | 44 | public String[] getNames() { 45 | return this.names; 46 | } 47 | 48 | public String getDescription() { 49 | return this.description; 50 | } 51 | 52 | public String getHelp() { 53 | return this.help; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/executor/CommandExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.executor; 19 | 20 | public interface CommandExecutor { 21 | 22 | void sendMessage(final String message); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/executor/ConsoleCommandExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.executor; 19 | 20 | import net.raphimc.viaproxy.util.logging.Logger; 21 | 22 | public class ConsoleCommandExecutor implements CommandExecutor { 23 | 24 | public static final ConsoleCommandExecutor INSTANCE = new ConsoleCommandExecutor(); 25 | 26 | private ConsoleCommandExecutor() { 27 | } 28 | 29 | @Override 30 | public void sendMessage(final String message) { 31 | Logger.LOGGER.info(message); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/impl/GcCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.impl; 19 | 20 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 21 | import net.raphimc.viaproxy.cli.command.Command; 22 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 23 | 24 | public class GcCommand extends Command { 25 | 26 | public GcCommand() { 27 | super("gc", "Perform JVM garbage collection", "gc"); 28 | } 29 | 30 | @Override 31 | public void register(final LiteralArgumentBuilder builder) { 32 | builder.executes(context -> { 33 | System.gc(); 34 | context.getSource().sendMessage("Performed garbage collection."); 35 | return 1; 36 | }); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/impl/HelpCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.impl; 19 | 20 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 21 | import net.raphimc.viaproxy.cli.command.Command; 22 | import net.raphimc.viaproxy.cli.command.CommandManager; 23 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 24 | 25 | public class HelpCommand extends Command { 26 | 27 | private final CommandManager commandManager; 28 | 29 | public HelpCommand(final CommandManager commandManager) { 30 | super("help", "Print a list of available commands and their arguments", "help"); 31 | this.commandManager = commandManager; 32 | } 33 | 34 | @Override 35 | public void register(final LiteralArgumentBuilder builder) { 36 | builder 37 | .executes(context -> { 38 | final CommandExecutor executor = context.getSource(); 39 | for (Command command : this.commandManager.getCommands()) { 40 | executor.sendMessage(command.getName() + " (" + command.getDescription() + "): " + command.getHelp()); 41 | } 42 | return 1; 43 | }); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/impl/StopCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.impl; 19 | 20 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 21 | import net.raphimc.viaproxy.cli.command.Command; 22 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 23 | 24 | public class StopCommand extends Command { 25 | 26 | public StopCommand() { 27 | super("stop", "Stop ViaProxy", "stop", "exit", "end"); 28 | } 29 | 30 | @Override 31 | public void register(final LiteralArgumentBuilder builder) { 32 | builder.executes(context -> { 33 | context.getSource().sendMessage("Stopping ViaProxy..."); 34 | System.exit(0); 35 | return 1; 36 | }); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/impl/ThreadDumpCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.impl; 19 | 20 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 21 | import net.raphimc.viaproxy.cli.command.Command; 22 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 23 | 24 | public class ThreadDumpCommand extends Command { 25 | 26 | public ThreadDumpCommand() { 27 | super("threaddump", "Print the stacktrace of the currently running threads", "threaddump"); 28 | } 29 | 30 | @Override 31 | public void register(final LiteralArgumentBuilder builder) { 32 | builder.executes(context -> { 33 | StringBuilder dump = new StringBuilder(); 34 | Thread.getAllStackTraces().forEach((thread, stackTrace) -> { 35 | dump.append(thread.getName()).append(":\n"); 36 | for (StackTraceElement element : stackTrace) { 37 | dump.append("\tat ").append(element).append("\n"); 38 | } 39 | }); 40 | context.getSource().sendMessage(dump.toString()); 41 | return 1; 42 | }); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/cli/command/impl/ViaVersionCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.cli.command.impl; 19 | 20 | import com.mojang.brigadier.arguments.StringArgumentType; 21 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 22 | import com.viaversion.viaversion.api.Via; 23 | import net.raphimc.viaproxy.cli.command.Command; 24 | import net.raphimc.viaproxy.cli.command.executor.CommandExecutor; 25 | import net.raphimc.viaproxy.protocoltranslator.viaproxy.ConsoleCommandSender; 26 | 27 | public class ViaVersionCommand extends Command { 28 | 29 | public ViaVersionCommand() { 30 | super("viaversion", "Execute a ViaVersion command", "viaversion ", "via", "vv"); 31 | } 32 | 33 | @Override 34 | public void register(final LiteralArgumentBuilder builder) { 35 | builder.then(argument("args", StringArgumentType.greedyString()).executes(context -> { 36 | Via.getManager().getCommandHandler().onCommand(new ConsoleCommandSender(), StringArgumentType.getString(context, "args").split(" ")); 37 | return 1; 38 | })); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/TransformerDowngrader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection; 19 | 20 | import net.lenni0451.classtransform.transformer.IAnnotationHandlerPreprocessor; 21 | import net.lenni0451.classtransform.utils.ASMUtils; 22 | import net.lenni0451.classtransform.utils.Sneaky; 23 | import org.objectweb.asm.tree.ClassNode; 24 | import xyz.wagyourtail.jvmdg.runtime.ClassDowngradingAgent; 25 | 26 | import java.lang.instrument.IllegalClassFormatException; 27 | 28 | public class TransformerDowngrader implements IAnnotationHandlerPreprocessor { 29 | 30 | private final ClassLoader classLoader; 31 | private final ClassDowngradingAgent downgrader = new ClassDowngradingAgent(); 32 | 33 | public TransformerDowngrader(final ClassLoader classLoader) { 34 | this.classLoader = classLoader; 35 | } 36 | 37 | @Override 38 | public void process(final ClassNode node) { 39 | } 40 | 41 | @Override 42 | public ClassNode replace(final ClassNode node) { 43 | final byte[] bytes = ASMUtils.toStacklessBytes(node); 44 | try { 45 | final byte[] transformed = this.downgrader.transform(this.classLoader, node.name, null, null, bytes); 46 | if (transformed != null) { 47 | return ASMUtils.fromBytes(transformed); 48 | } else { 49 | return node; 50 | } 51 | } catch (IllegalClassFormatException e) { 52 | Sneaky.sneakyThrow(e); 53 | return null; 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinBlockItemPacketRewriter1_21_4.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; 21 | import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.rewriter.BlockItemPacketRewriter1_21_4; 22 | import net.raphimc.vialegacy.api.LegacyProtocolVersion; 23 | import org.spongepowered.asm.mixin.Mixin; 24 | import org.spongepowered.asm.mixin.injection.At; 25 | import org.spongepowered.asm.mixin.injection.Redirect; 26 | 27 | @Mixin(value = BlockItemPacketRewriter1_21_4.class, remap = false) 28 | public abstract class MixinBlockItemPacketRewriter1_21_4 { 29 | 30 | @Redirect(method = "appendItemDataFixComponents", at = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/api/protocol/version/ProtocolVersion;olderThanOrEqualTo(Lcom/viaversion/viaversion/api/protocol/version/ProtocolVersion;)Z")) 31 | private boolean changeSwordFixVersionRange(ProtocolVersion instance, ProtocolVersion other) { 32 | if (other == ProtocolVersion.v1_8) { 33 | return instance.betweenInclusive(LegacyProtocolVersion.b1_8tob1_8_1, ProtocolVersion.v1_8); 34 | } else { 35 | return instance.olderThanOrEqualTo(other); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinC2SHandshakingClientIntentionPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import net.raphimc.netminecraft.packet.impl.handshaking.C2SHandshakingClientIntentionPacket; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.injection.Constant; 23 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 24 | 25 | @Mixin(C2SHandshakingClientIntentionPacket.class) 26 | public abstract class MixinC2SHandshakingClientIntentionPacket { 27 | 28 | @ModifyConstant(method = "read", constant = @Constant(intValue = 255)) 29 | private int allowLargerHostnames(int constant) { 30 | return Short.MAX_VALUE; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinCommonBoss.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.legacy.bossbar.CommonBoss; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.injection.At; 23 | import org.spongepowered.asm.mixin.injection.Redirect; 24 | 25 | @Mixin(value = CommonBoss.class, remap = false) 26 | public abstract class MixinCommonBoss { 27 | 28 | @Redirect(method = {"", "setHealth"}, at = @At(value = "INVOKE", target = "Lcom/google/common/base/Preconditions;checkArgument(ZLjava/lang/Object;)V")) 29 | private void removeBoundChecks(boolean expression, Object errorMessage) { 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinConfigurationState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; 21 | import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4; 22 | import com.viaversion.viaversion.protocols.v1_20to1_20_2.storage.ConfigurationState; 23 | import net.raphimc.viaproxy.ViaProxy; 24 | import org.spongepowered.asm.mixin.Mixin; 25 | import org.spongepowered.asm.mixin.injection.At; 26 | import org.spongepowered.asm.mixin.injection.Inject; 27 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 28 | 29 | @Mixin(value = ConfigurationState.class, remap = false) 30 | public abstract class MixinConfigurationState { 31 | 32 | @Inject(method = "addPacketToQueue", at = @At("HEAD"), cancellable = true) 33 | private void cancelQueuedPackets(PacketWrapper wrapper, boolean clientbound, CallbackInfo ci) { 34 | // Dirty workaround for https://github.com/ViaVersion/ViaVersion/issues/4308 where queued packets 35 | // without set packet type cause a disconnect after sent in play state, even when delayed until the client 36 | // has transitioned to the play state as well. This is *very* bad as in worst will cause data loss and other 37 | // issues but /shrug for now. 38 | if (ViaProxy.getConfig().shouldWorkAroundConfigStatePacketQueue() && clientbound && wrapper.getPacketType() == null) { 39 | final int unmappedId = wrapper.getId(); 40 | if (unmappedId == ClientboundPackets1_19_4.CONTAINER_CLOSE.getId() || unmappedId == ClientboundPackets1_19_4.CHUNKS_BIOMES.getId() || unmappedId == ClientboundPackets1_19_4.SET_ENTITY_MOTION.getId()) { 41 | ci.cancel(); 42 | } 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinEntityPacketRewriter1_17.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.protocol.Protocol; 21 | import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; 22 | import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; 23 | import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2; 24 | import com.viaversion.viaversion.protocols.v1_16_4to1_17.Protocol1_16_4To1_17; 25 | import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.EntityPacketRewriter1_17; 26 | import net.raphimc.viaproxy.injection.ClassicWorldHeightInjection; 27 | import org.spongepowered.asm.mixin.Mixin; 28 | import org.spongepowered.asm.mixin.injection.At; 29 | import org.spongepowered.asm.mixin.injection.Redirect; 30 | 31 | @Mixin(value = EntityPacketRewriter1_17.class, remap = false) 32 | public abstract class MixinEntityPacketRewriter1_17 { 33 | 34 | @Redirect(method = "registerPackets", at = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17;registerClientbound(Lcom/viaversion/viaversion/api/protocol/packet/ClientboundPacketType;Lcom/viaversion/viaversion/api/protocol/remapper/PacketHandler;)V")) 35 | private void handleClassicWorldHeight(Protocol1_16_4To1_17 instance, ClientboundPacketType packetType, PacketHandler packetHandler) { 36 | if (packetType == ClientboundPackets1_16_2.LOGIN) packetHandler = ClassicWorldHeightInjection.handleJoinGame(packetHandler); 37 | if (packetType == ClientboundPackets1_16_2.RESPAWN) packetHandler = ClassicWorldHeightInjection.handleRespawn(packetHandler); 38 | 39 | ((Protocol) instance).registerClientbound(packetType, packetHandler); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinEntityTracker1_9.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; 21 | import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Redirect; 25 | import org.spongepowered.asm.mixin.injection.Slice; 26 | 27 | @Mixin(value = EntityTracker1_9.class, remap = false) 28 | public abstract class MixinEntityTracker1_9 { 29 | 30 | @Redirect(method = "handleEntityData", at = @At(value = "INVOKE", target = "Ljava/lang/Math;min(FF)F"), slice = @Slice(from = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/api/configuration/ViaVersionConfig;isBossbarAntiflicker()Z"))) 31 | private float removeMin(float a, float b) { 32 | return a; 33 | } 34 | 35 | @Redirect(method = "handleEntityData", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F"), slice = @Slice(from = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/api/configuration/ViaVersionConfig;isBossbarAntiflicker()Z"))) 36 | private float removeMax(float a, float b) { 37 | return b; 38 | } 39 | 40 | @Redirect(method = "handleEntityData", at = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/api/minecraft/entitydata/EntityData;getValue()Ljava/lang/Object;"), slice = @Slice(from = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/api/configuration/ViaVersionConfig;isBossbarAntiflicker()Z"))) 41 | private Object remapNaNToZero(EntityData instance) { 42 | if (instance.getValue() instanceof Float && ((Float) instance.getValue()).isNaN()) { 43 | return 0F; 44 | } 45 | 46 | return instance.getValue(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinPluginManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import org.apache.logging.log4j.Logger; 21 | import org.apache.logging.log4j.core.config.plugins.util.PluginManager; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Redirect; 25 | 26 | @Mixin(PluginManager.class) 27 | public abstract class MixinPluginManager { 28 | 29 | @Redirect(method = "collectPlugins(Ljava/util/List;)V", at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V")) 30 | private void dontLogWarning(Logger logger, String message, Object p0, Object p1, Object p2) { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_18To1_18_2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.connection.UserConnection; 21 | import com.viaversion.viaversion.api.protocol.AbstractProtocol; 22 | import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; 23 | import com.viaversion.viaversion.api.type.Types; 24 | import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17; 25 | import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18; 26 | import com.viaversion.viaversion.protocols.v1_18to1_18_2.Protocol1_18To1_18_2; 27 | import net.raphimc.viaproxy.protocoltranslator.viaproxy.loading_terrain_fix.SpawnPositionTracker; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.injection.At; 30 | import org.spongepowered.asm.mixin.injection.Inject; 31 | 32 | @Mixin(Protocol1_18To1_18_2.class) 33 | public abstract class MixinProtocol1_18To1_18_2 extends AbstractProtocol { 34 | 35 | @Inject(method = "registerPackets", at = @At("RETURN")) 36 | private void fixDownloadingTerrainScreenNotClosing() { 37 | this.registerClientbound(ClientboundPackets1_18.PLAYER_POSITION, new PacketHandlers() { 38 | @Override 39 | public void register() { 40 | handler(wrapper -> wrapper.user().get(SpawnPositionTracker.class).sendSpawnPosition()); 41 | } 42 | }); 43 | this.registerClientbound(ClientboundPackets1_18.SET_DEFAULT_SPAWN_POSITION, new PacketHandlers() { 44 | @Override 45 | public void register() { 46 | map(Types.BLOCK_POSITION1_14); // position 47 | map(Types.FLOAT); // angle 48 | handler(wrapper -> wrapper.user().get(SpawnPositionTracker.class).setSpawnPosition(wrapper.get(Types.BLOCK_POSITION1_14, 0), wrapper.get(Types.FLOAT, 0))); 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | public void init(UserConnection user) { 55 | user.put(new SpawnPositionTracker(user)); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_20To1_20_2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; 21 | import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4; 22 | import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2; 23 | import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2; 24 | import net.raphimc.viaproxy.ViaProxy; 25 | import org.spongepowered.asm.mixin.Mixin; 26 | import org.spongepowered.asm.mixin.injection.At; 27 | import org.spongepowered.asm.mixin.injection.Inject; 28 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 29 | 30 | @Mixin(value = Protocol1_20To1_20_2.class, remap = false) 31 | public abstract class MixinProtocol1_20To1_20_2 { 32 | 33 | @Inject(method = "lambda$queueServerboundPacket$12", at = @At("HEAD"), cancellable = true) 34 | private static void dontQueueConfigPackets(ServerboundPackets1_20_2 packetType, PacketWrapper wrapper, CallbackInfo ci) { 35 | if (ViaProxy.getConfig().shouldSkipConfigStatePacketQueue()) { 36 | ci.cancel(); 37 | switch (packetType) { 38 | case CUSTOM_PAYLOAD -> wrapper.setPacketType(ServerboundPackets1_19_4.CUSTOM_PAYLOAD); 39 | case KEEP_ALIVE -> wrapper.setPacketType(ServerboundPackets1_19_4.KEEP_ALIVE); 40 | case PONG -> wrapper.setPacketType(ServerboundPackets1_19_4.PONG); 41 | default -> throw new IllegalStateException("Unexpected packet type: " + packetType); 42 | } 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinViaLegacyConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import net.raphimc.vialegacy.ViaLegacyConfig; 21 | import net.raphimc.viaproxy.ViaProxy; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Inject; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 26 | 27 | @Mixin(ViaLegacyConfig.class) 28 | public abstract class MixinViaLegacyConfig { 29 | 30 | @Inject(method = "isLegacySkinLoading", at = @At("HEAD"), cancellable = true) 31 | private void makeGUIConfigurable1(final CallbackInfoReturnable cir) { 32 | if (ViaProxy.getViaProxyWindow() != null) { 33 | cir.setReturnValue(ViaProxy.getViaProxyWindow().advancedTab.legacySkinLoading.isSelected()); 34 | } 35 | } 36 | 37 | @Inject(method = "isLegacySkullLoading", at = @At("HEAD"), cancellable = true) 38 | private void makeGUIConfigurable2(final CallbackInfoReturnable cir) { 39 | if (ViaProxy.getViaProxyWindow() != null) { 40 | cir.setReturnValue(ViaProxy.getViaProxyWindow().advancedTab.legacySkinLoading.isSelected()); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinWorldPacketRewriter1_16_2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.WorldPacketRewriter1_16_2; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.injection.Constant; 23 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 24 | 25 | @Mixin(value = WorldPacketRewriter1_16_2.class, remap = false) 26 | public abstract class MixinWorldPacketRewriter1_16_2 { 27 | 28 | @ModifyConstant(method = "lambda$register$0", constant = @Constant(intValue = 16)) 29 | private static int modifySectionCountToSupportClassicWorldHeight(int constant) { 30 | return 64; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/injection/mixins/MixinWorldPacketRewriter1_17.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.injection.mixins; 19 | 20 | import com.viaversion.viaversion.api.protocol.Protocol; 21 | import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; 22 | import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; 23 | import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2; 24 | import com.viaversion.viaversion.protocols.v1_16_4to1_17.Protocol1_16_4To1_17; 25 | import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.WorldPacketRewriter1_17; 26 | import net.raphimc.viaproxy.injection.ClassicWorldHeightInjection; 27 | import org.spongepowered.asm.mixin.Mixin; 28 | import org.spongepowered.asm.mixin.injection.At; 29 | import org.spongepowered.asm.mixin.injection.Redirect; 30 | 31 | @Mixin(value = WorldPacketRewriter1_17.class, remap = false) 32 | public abstract class MixinWorldPacketRewriter1_17 { 33 | 34 | @Redirect(method = "register", at = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17;registerClientbound(Lcom/viaversion/viaversion/api/protocol/packet/ClientboundPacketType;Lcom/viaversion/viaversion/api/protocol/remapper/PacketHandler;)V")) 35 | private static void handleClassicWorldHeight(Protocol1_16_4To1_17 instance, ClientboundPacketType packetType, PacketHandler packetHandler) { 36 | if (packetType == ClientboundPackets1_16_2.LEVEL_CHUNK) packetHandler = ClassicWorldHeightInjection.handleChunkData(packetHandler); 37 | if (packetType == ClientboundPackets1_16_2.LIGHT_UPDATE) packetHandler = ClassicWorldHeightInjection.handleUpdateLight(packetHandler); 38 | 39 | ((Protocol) instance).registerClientbound(packetType, packetHandler); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/ViaProxyPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins; 19 | 20 | import java.io.File; 21 | import java.net.URLClassLoader; 22 | import java.util.Collections; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | public abstract class ViaProxyPlugin { 27 | 28 | private URLClassLoader classLoader; 29 | private Map viaProxyYaml; 30 | private boolean enabled; 31 | 32 | final void init(final URLClassLoader classLoader, final Map viaProxyYaml) { 33 | this.classLoader = classLoader; 34 | this.viaProxyYaml = viaProxyYaml; 35 | } 36 | 37 | final void enable() { 38 | this.onEnable(); 39 | this.enabled = true; 40 | } 41 | 42 | public abstract void onEnable(); 43 | 44 | final void disable() { 45 | try { 46 | this.onDisable(); 47 | } finally { 48 | this.enabled = false; 49 | } 50 | } 51 | 52 | public void onDisable() { 53 | } 54 | 55 | public final File getDataFolder() { 56 | final File dataFolder = new File(PluginManager.PLUGINS_DIR, (String) this.viaProxyYaml.get("name")); 57 | if (!dataFolder.exists()) { 58 | dataFolder.mkdirs(); 59 | } 60 | return dataFolder; 61 | } 62 | 63 | public final String getName() { 64 | return (String) this.viaProxyYaml.get("name"); 65 | } 66 | 67 | public final String getAuthor() { 68 | return (String) this.viaProxyYaml.get("author"); 69 | } 70 | 71 | public final String getVersion() { 72 | return String.valueOf(this.viaProxyYaml.get("version")); 73 | } 74 | 75 | public final List getDepends() { 76 | return Collections.unmodifiableList((List) this.viaProxyYaml.getOrDefault("depends", Collections.emptyList())); 77 | } 78 | 79 | public final URLClassLoader getClassLoader() { 80 | return this.classLoader; 81 | } 82 | 83 | public final boolean isEnabled() { 84 | return this.enabled; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/Client2ProxyChannelInitializeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import io.netty.channel.Channel; 21 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 22 | import net.raphimc.viaproxy.plugins.events.types.ITyped; 23 | 24 | public class Client2ProxyChannelInitializeEvent extends EventCancellable implements ITyped { 25 | 26 | private final Type type; 27 | private final Channel channel; 28 | private final boolean isLegacyPassthrough; 29 | 30 | public Client2ProxyChannelInitializeEvent(final Type type, final Channel channel, final boolean isLegacyPassthrough) { 31 | this.type = type; 32 | this.channel = channel; 33 | this.isLegacyPassthrough = isLegacyPassthrough; 34 | } 35 | 36 | public Channel getChannel() { 37 | return this.channel; 38 | } 39 | 40 | public boolean isLegacyPassthrough() { 41 | return this.isLegacyPassthrough; 42 | } 43 | 44 | 45 | @Override 46 | public Type getType() { 47 | return this.type; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/Client2ProxyHandlerCreationEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import io.netty.channel.ChannelHandler; 21 | 22 | public class Client2ProxyHandlerCreationEvent { 23 | 24 | /** 25 | * The handler which will be used to handle Client<->Proxy packets. 26 | */ 27 | private ChannelHandler handler; 28 | 29 | /** 30 | * Whether the handler is a legacy passthrough handler. 31 | */ 32 | private final boolean isLegacyPassthrough; 33 | 34 | public Client2ProxyHandlerCreationEvent(final ChannelHandler handler, final boolean isLegacyPassthrough) { 35 | this.handler = handler; 36 | this.isLegacyPassthrough = isLegacyPassthrough; 37 | } 38 | 39 | public ChannelHandler getHandler() { 40 | return this.handler; 41 | } 42 | 43 | public void setHandler(final ChannelHandler handler) { 44 | this.handler = handler; 45 | } 46 | 47 | public boolean isLegacyPassthrough() { 48 | return this.isLegacyPassthrough; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ClientLoggedInEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 21 | 22 | public class ClientLoggedInEvent { 23 | 24 | private final ProxyConnection proxyConnection; 25 | 26 | public ClientLoggedInEvent(final ProxyConnection proxyConnection) { 27 | this.proxyConnection = proxyConnection; 28 | } 29 | 30 | public ProxyConnection getProxyConnection() { 31 | return this.proxyConnection; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ConnectEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 21 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 22 | 23 | public class ConnectEvent extends EventCancellable { 24 | 25 | private final ProxyConnection proxyConnection; 26 | 27 | public ConnectEvent(final ProxyConnection proxyConnection) { 28 | this.proxyConnection = proxyConnection; 29 | } 30 | 31 | public ProxyConnection getProxyConnection() { 32 | return this.proxyConnection; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ConsoleCommandEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 21 | 22 | public class ConsoleCommandEvent extends EventCancellable { 23 | 24 | private final String command; 25 | private final String[] args; 26 | 27 | public ConsoleCommandEvent(final String command, final String[] args) { 28 | this.command = command; 29 | this.args = args; 30 | } 31 | 32 | public String getCommand() { 33 | return this.command; 34 | } 35 | 36 | public String[] getArgs() { 37 | return this.args; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/FillPlayerDataEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 21 | 22 | public class FillPlayerDataEvent { 23 | 24 | private final ProxyConnection proxyConnection; 25 | 26 | public FillPlayerDataEvent(final ProxyConnection proxyConnection) { 27 | this.proxyConnection = proxyConnection; 28 | } 29 | 30 | public ProxyConnection getProxyConnection() { 31 | return this.proxyConnection; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/JoinServerRequestEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 21 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 22 | 23 | public class JoinServerRequestEvent extends EventCancellable { 24 | 25 | private final ProxyConnection proxyConnection; 26 | private final String serverIdHash; 27 | 28 | public JoinServerRequestEvent(final ProxyConnection proxyConnection, final String serverIdHash) { 29 | this.proxyConnection = proxyConnection; 30 | this.serverIdHash = serverIdHash; 31 | } 32 | 33 | public ProxyConnection getProxyConnection() { 34 | return this.proxyConnection; 35 | } 36 | 37 | public String getServerIdHash() { 38 | return this.serverIdHash; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/PostOptionsParseEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import joptsimple.OptionSet; 21 | 22 | public class PostOptionsParseEvent { 23 | 24 | private final OptionSet options; 25 | 26 | public PostOptionsParseEvent(final OptionSet options) { 27 | this.options = options; 28 | } 29 | 30 | public OptionSet getOptions() { 31 | return this.options; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/PreOptionsParseEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import joptsimple.OptionParser; 21 | 22 | public class PreOptionsParseEvent { 23 | 24 | private final OptionParser parser; 25 | 26 | public PreOptionsParseEvent(final OptionParser parser) { 27 | this.parser = parser; 28 | } 29 | 30 | public OptionParser getParser() { 31 | return this.parser; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ProtocolTranslatorInitEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.function.Supplier; 23 | 24 | public class ProtocolTranslatorInitEvent { 25 | 26 | private final List> additionalPlatformSuppliers = new ArrayList<>(); 27 | 28 | public ProtocolTranslatorInitEvent(final Supplier... additionalPlatformSuppliers) { 29 | for (final Supplier platformSupplier : additionalPlatformSuppliers) { 30 | this.registerPlatform(platformSupplier); 31 | } 32 | } 33 | 34 | public void registerPlatform(final Supplier platformSupplier) { 35 | this.additionalPlatformSuppliers.add(platformSupplier); 36 | } 37 | 38 | public List> getPlatformSuppliers() { 39 | return this.additionalPlatformSuppliers; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/Proxy2ServerChannelInitializeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import io.netty.channel.Channel; 21 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 22 | import net.raphimc.viaproxy.plugins.events.types.ITyped; 23 | 24 | public class Proxy2ServerChannelInitializeEvent extends EventCancellable implements ITyped { 25 | 26 | private final Type type; 27 | private final Channel channel; 28 | private final boolean isLegacyPassthrough; 29 | 30 | public Proxy2ServerChannelInitializeEvent(final Type type, final Channel channel, final boolean isLegacyPassthrough) { 31 | this.type = type; 32 | this.channel = channel; 33 | this.isLegacyPassthrough = isLegacyPassthrough; 34 | } 35 | 36 | public Channel getChannel() { 37 | return this.channel; 38 | } 39 | 40 | public boolean isLegacyPassthrough() { 41 | return this.isLegacyPassthrough; 42 | } 43 | 44 | 45 | @Override 46 | public Type getType() { 47 | return this.type; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/Proxy2ServerHandlerCreationEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import io.netty.channel.ChannelHandler; 21 | 22 | public class Proxy2ServerHandlerCreationEvent { 23 | 24 | /** 25 | * The handler which will be used to handle Proxy<->Server packets. 26 | */ 27 | private ChannelHandler handler; 28 | 29 | /** 30 | * Whether the handler is a legacy passthrough handler. 31 | */ 32 | private final boolean isLegacyPassthrough; 33 | 34 | public Proxy2ServerHandlerCreationEvent(final ChannelHandler handler, final boolean isLegacyPassthrough) { 35 | this.handler = handler; 36 | this.isLegacyPassthrough = isLegacyPassthrough; 37 | } 38 | 39 | public ChannelHandler getHandler() { 40 | return this.handler; 41 | } 42 | 43 | public void setHandler(final ChannelHandler handler) { 44 | this.handler = handler; 45 | } 46 | 47 | public boolean isLegacyPassthrough() { 48 | return this.isLegacyPassthrough; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ProxySessionCreationEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.netminecraft.netty.connection.NetClient; 21 | 22 | public class ProxySessionCreationEvent { 23 | 24 | /** 25 | * The proxy session which will be used to connect to the server and store connection related data. 26 | */ 27 | private T proxySession; 28 | 29 | /** 30 | * Whether the proxy session is a legacy passthrough handler. 31 | */ 32 | private final boolean isLegacyPassthrough; 33 | 34 | public ProxySessionCreationEvent(final T proxySession, final boolean isLegacyPassthrough) { 35 | this.proxySession = proxySession; 36 | this.isLegacyPassthrough = isLegacyPassthrough; 37 | } 38 | 39 | public T getProxySession() { 40 | return this.proxySession; 41 | } 42 | 43 | public void setProxySession(final T proxySession) { 44 | this.proxySession = proxySession; 45 | } 46 | 47 | public boolean isLegacyPassthrough() { 48 | return this.isLegacyPassthrough; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ProxyStartEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | public class ProxyStartEvent { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ProxyStopEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | public class ProxyStopEvent { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ShouldVerifyOnlineModeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | import net.raphimc.viaproxy.plugins.events.types.EventCancellable; 21 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 22 | 23 | public class ShouldVerifyOnlineModeEvent extends EventCancellable { 24 | 25 | private final ProxyConnection proxyConnection; 26 | 27 | public ShouldVerifyOnlineModeEvent(final ProxyConnection proxyConnection) { 28 | this.proxyConnection = proxyConnection; 29 | } 30 | 31 | public ProxyConnection getProxyConnection() { 32 | return this.proxyConnection; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ViaLoadingEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | public class ViaLoadingEvent { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/ViaProxyLoadedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events; 19 | 20 | public class ViaProxyLoadedEvent { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/types/EventCancellable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events.types; 19 | 20 | import net.lenni0451.lambdaevents.types.ICancellableEvent; 21 | 22 | public abstract class EventCancellable implements ICancellableEvent { 23 | 24 | private boolean cancelled = false; 25 | 26 | @Override 27 | public boolean isCancelled() { 28 | return this.cancelled; 29 | } 30 | 31 | public void setCancelled(final boolean cancelled) { 32 | this.cancelled = cancelled; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/plugins/events/types/ITyped.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.plugins.events.types; 19 | 20 | public interface ITyped { 21 | 22 | Type getType(); 23 | 24 | 25 | enum Type { 26 | PRE, POST 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyVLPipeline.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.protocoltranslator.impl; 19 | 20 | import com.viaversion.vialoader.netty.VLPipeline; 21 | import com.viaversion.viaversion.api.connection.UserConnection; 22 | import io.netty.channel.ChannelHandler; 23 | import net.raphimc.netminecraft.constants.MCPipeline; 24 | 25 | public class ViaProxyVLPipeline extends VLPipeline { 26 | 27 | public ViaProxyVLPipeline(final UserConnection user) { 28 | super(user); 29 | } 30 | 31 | @Override 32 | public ChannelHandler createViaCodec() { 33 | return new ViaProxyViaCodec(this.connection); 34 | } 35 | 36 | @Override 37 | protected String compressionCodecName() { 38 | return MCPipeline.COMPRESSION_HANDLER_NAME; 39 | } 40 | 41 | @Override 42 | protected String packetCodecName() { 43 | return MCPipeline.PACKET_CODEC_HANDLER_NAME; 44 | } 45 | 46 | @Override 47 | protected String lengthCodecName() { 48 | return MCPipeline.SIZER_HANDLER_NAME; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.protocoltranslator.impl; 19 | 20 | import com.viaversion.vialoader.netty.ViaCodec; 21 | import com.viaversion.viaversion.api.connection.UserConnection; 22 | import io.netty.channel.ChannelHandlerContext; 23 | import net.raphimc.viaproxy.ViaProxy; 24 | import net.raphimc.viaproxy.util.logging.Logger; 25 | 26 | public class ViaProxyViaCodec extends ViaCodec { 27 | 28 | public ViaProxyViaCodec(UserConnection user) { 29 | super(user); 30 | } 31 | 32 | @Override 33 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 34 | if (ViaProxy.getConfig().shouldIgnoreProtocolTranslationErrors()) { 35 | try { 36 | super.channelRead(ctx, msg); 37 | } catch (Throwable e) { 38 | Logger.LOGGER.error("ProtocolTranslator packet translation error occurred", e); 39 | } 40 | } else { 41 | super.channelRead(ctx, msg); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaLegacyPlatformImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.protocoltranslator.impl; 19 | 20 | import com.viaversion.vialoader.impl.platform.ViaLegacyPlatformImpl; 21 | import com.viaversion.viaversion.api.Via; 22 | 23 | public class ViaProxyViaLegacyPlatformImpl extends ViaLegacyPlatformImpl { 24 | 25 | @Override 26 | public String getCpeAppName() { 27 | return Via.getPlatform().getPlatformName() + " " + Via.getPlatform().getPlatformVersion(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaVersionPlatformImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.protocoltranslator.impl; 19 | 20 | import com.viaversion.vialoader.impl.platform.ViaVersionPlatformImpl; 21 | import com.viaversion.viaversion.api.connection.UserConnection; 22 | import com.viaversion.viaversion.libs.gson.JsonArray; 23 | import com.viaversion.viaversion.libs.gson.JsonObject; 24 | import net.raphimc.viaproxy.ViaProxy; 25 | import net.raphimc.viaproxy.plugins.ViaProxyPlugin; 26 | import net.raphimc.viaproxy.proxy.session.ProxyConnection; 27 | import net.raphimc.viaproxy.proxy.util.CloseAndReturn; 28 | 29 | public class ViaProxyViaVersionPlatformImpl extends ViaVersionPlatformImpl { 30 | 31 | public ViaProxyViaVersionPlatformImpl() { 32 | super(ViaProxy.getCwd()); 33 | } 34 | 35 | @Override 36 | public String getPlatformName() { 37 | return "ViaProxy"; 38 | } 39 | 40 | @Override 41 | public String getPlatformVersion() { 42 | return ViaProxy.VERSION; 43 | } 44 | 45 | @Override 46 | public boolean kickPlayer(UserConnection connection, String message) { 47 | try { 48 | ProxyConnection.fromUserConnection(connection).kickClient(message); 49 | } catch (CloseAndReturn ignored) { 50 | } 51 | return true; 52 | } 53 | 54 | @Override 55 | public JsonObject getDump() { 56 | final JsonObject root = new JsonObject(); 57 | 58 | root.addProperty("impl_version", ViaProxy.IMPL_VERSION); 59 | 60 | final JsonArray plugins = new JsonArray(); 61 | for (ViaProxyPlugin plugin : ViaProxy.getPluginManager().getPlugins()) { 62 | final JsonObject pluginObj = new JsonObject(); 63 | pluginObj.addProperty("name", plugin.getName()); 64 | pluginObj.addProperty("version", plugin.getVersion()); 65 | pluginObj.addProperty("author", plugin.getAuthor()); 66 | plugins.add(pluginObj); 67 | } 68 | root.add("plugins", plugins); 69 | 70 | return root; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyClassicCustomCommandProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy 3 | * Copyright (C) 2021-2025 RK_01/RaphiMC and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.raphimc.viaproxy.protocoltranslator.providers; 19 | 20 | import com.viaversion.viaversion.api.connection.UserConnection; 21 | import net.raphimc.vialegacy.ViaLegacy; 22 | import net.raphimc.vialegacy.protocol.alpha.a1_0_16_2toa1_0_17_1_0_17_4.storage.TimeLockStorage; 23 | import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.provider.ClassicCustomCommandProvider; 24 | 25 | import java.util.logging.Level; 26 | 27 | public class ViaProxyClassicCustomCommandProvider extends ClassicCustomCommandProvider { 28 | 29 | @Override 30 | public boolean handleChatMessage(UserConnection user, String message) { 31 | try { 32 | if (message.startsWith("/")) { 33 | message = message.substring(1); 34 | final String[] args = message.split(" "); 35 | if (args.length == 0) return super.handleChatMessage(user, message); 36 | if (args[0].equals("settime")) { 37 | try { 38 | if (args.length > 1) { 39 | final long time = Long.parseLong(args[1]) % 24_000L; 40 | user.get(TimeLockStorage.class).setTime(time); 41 | this.sendFeedback(user, "§aTime has been set to §6" + time); 42 | } else { 43 | throw new RuntimeException("Invalid usage"); 44 | } 45 | } catch (Throwable ignored) { 46 | this.sendFeedback(user, "§cUsage: /settime