Compare commits

...

92 Commits

Author SHA1 Message Date
Dawson 9cbeed1df3 58-bug-plugin-fails-to-load-after-upgrading-to-193-on-velocity (#60)
* Moving to previous H2 version that was in 1.9.2 that somehow got downgraded

* Reverting back to Java 8 compile target

* removing minimize on shade for Common

* Clearly something here changed something, cause reverting it this way seems to have fixed it

* Cleaning up code here

---------

Co-authored-by: Dawson <dawson@funkemunky.cc>
2025-03-27 10:44:34 -04:00
Dawson 353b7dad78 bugfix/velocity-kick (#56)
* Updating velocity API

* Added exception logging and fixed NullPointerException with antivpn plan command in velocity from tab-complete being null. Replaced MySQL with MariaDB driver

* Added exception logging and fixed NullPointerException with antivpn plan command in velocity from tab-complete being null. Replaced MySQL with MariaDB driver.

* Added exception logging and fixed NullPointerException with antivpn plan command in velocity from tab-complete being null. Replaced MySQL with MariaDB driver.

* Fixing kick reason

* Corrected MySQL ssl errors and fixed visual bug with velocity users kicking

* Reverted to mysql driver

---------

Co-authored-by: Dawson <dawson@funkemunky.cc>
2025-01-26 14:56:12 -05:00
dependabot[bot] 0291aca052 Merge pull request #52
* Bump com.h2database:h2 from 2.1.210 to 2.2.220 in /Common

* Merge branch 'master' into dependabot/maven/Common/com.h2database-h2-…

* Merge branch 'master' into dependabot/maven/Common/com.h2database-h2-…

* Updating mysql depends to non-vulnerable
2024-11-24 14:38:27 -05:00
funkemunky ae5893be89 Worflow now uses setup-java for caching as well. 2024-11-18 09:23:52 -05:00
funkemunky f9ed53bfec Updating action to latest versions 2024-11-18 09:19:23 -05:00
Dawson cb32dfc370 Allowing manual dispatch 2024-11-18 09:14:37 -05:00
Dawson 4c7ff3d061 Merge pull request #48 from funkemunky/bugfix-bukkit-login
Fixing bukkit and antivirus problems - Release v1.9.3
2024-03-17 14:23:42 -04:00
funkemunky aec0bb2738 Corrected error on bukkit servers when vanilla kicking players 2024-03-15 11:17:25 -04:00
funkemunky 3f5ab39877 - Correct command concurrency issues on Bukkit servers
- Removed dynamic class loading of libraries to fix antivirus flags of the plugin.
2024-03-15 11:06:49 -04:00
Dawson f2e59c0075 Merge pull request #47 from Michielo1/patch-1
Correct ISO codes link in config
2024-03-08 22:37:00 -05:00
Michielo a01b595953 Correct ISO codes link 2024-02-18 20:51:25 +01:00
funkemunky b2fcc4ff26 Changing event priority on bungee so KauriVPN checks run before anything else. 2024-01-25 13:24:51 -05:00
funkemunky 5363b7c469 In process of correcting kick issues 2024-01-06 19:56:14 -05:00
Dawson df48e3dfd4 Update issue templates 2023-12-31 13:39:31 -05:00
Dawson 0686c5fd3e Update issue templates 2023-12-31 13:38:17 -05:00
funkemunky 5b6d214e6f Patches bug on Bukkit/Spigot servers may result in some players not being kicked on VPN detection.
I believe this occurs when the API response is below 50ms, and we attempt to Player#kickPlayer() or run commands on console that attempt to kick the player. The problem is that if this is running before the tick PlayerLoginEvent runs on ends, the player wouldn't be considered "online". Therefore, the player would never be removed from the server even if desired.

I assumed wrongly that the async processing of the query would always end up on the next tick. So now I update the PlayerLoginEvent result to KICK_BANNED no matter if the processing is async or in the same thread stack as the event.
2023-12-30 14:06:44 -05:00
funkemunky 2bdd7d2c34 Cleaned up files 2023-12-04 08:55:01 -05:00
funkemunky 31a9412c0a Updated libraries, and cleaned up code for performance purposes. 2023-12-04 08:54:48 -05:00
Dawson Hessler 7f96c49ce8 Delete nightly.yml 2023-10-30 10:41:45 -04:00
Dawson Hessler 7b3f9fc6ae Update nightly.yml 2023-10-30 10:38:01 -04:00
Dawson Hessler edd08b27ce Update maven.yml 2023-10-30 10:37:36 -04:00
Dawson Hessler 158045217e Create nightly.yml 2023-10-30 10:37:01 -04:00
Dawson 63bdb0a4da Merge pull request #45 from funkemunky/dependabot/maven/Common/com.google.guava-guava-32.0.0-jre
Bump com.google.guava:guava from 31.1-jre to 32.0.0-jre in /Common
2023-10-30 10:27:05 -04:00
Dawson b9e23ba34e Updating to only run on commits and pull requests to main 2023-10-30 10:26:26 -04:00
dependabot[bot] 9f6b0f8b27 Bump com.google.guava:guava from 31.1-jre to 32.0.0-jre in /Common
Bumps [com.google.guava:guava](https://github.com/google/guava) from 31.1-jre to 32.0.0-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 14:24:01 +00:00
Dawson fec1dcdef1 Merge pull request #29 from funkemunky/dependabot/maven/Common/org.yaml-snakeyaml-2.0
Bump snakeyaml from 1.30 to 2.0 in /Common
2023-10-30 10:23:21 -04:00
Dawson Hessler c062e3d910 Tested and correcting dependency issues 2023-10-30 10:20:49 -04:00
Dawson Hessler a79fb1fe9a Updating more vulnerable depends 2023-10-30 10:14:15 -04:00
Dawson Hessler d224efce3c Updating depends to make it work 2023-10-30 10:12:14 -04:00
Dawson Hessler a2554c2bba Merge branch 'master' into dependabot/maven/Common/org.yaml-snakeyaml-2.0 2023-10-30 10:06:28 -04:00
Dawson 70bfb4e83d Merge pull request #42 from C0D3-M4513R/master
Fix PR #35
2023-10-30 10:06:07 -04:00
Dawson bc666447c5 Merge pull request #43 from C0D3-M4513R/patch-bukkit-banned-whitelist
Add null checks to ip check on login
2023-10-30 10:05:51 -04:00
Dawson Hessler 26cfc3e3f8 Update maven.yml 2023-10-30 10:03:04 -04:00
Dawson Hessler 7974b24271 Revert "Revert "Revert "Update maven.yml"""
This reverts commit 87cdd57383.
2023-10-30 10:02:30 -04:00
Dawson Hessler 87cdd57383 Revert "Revert "Update maven.yml""
This reverts commit 6fe928ca14.
2023-10-30 10:02:17 -04:00
Dawson Hessler 6fe928ca14 Revert "Update maven.yml"
This reverts commit d461b5945b.
2023-10-30 10:02:02 -04:00
Dawson Hessler dae9111a34 Revert "Merge branch 'master' of https://github.com/funkemunky/AntiVPN"
This reverts commit f4d6fc2b4b, reversing
changes made to d461b5945b.
2023-10-30 10:01:50 -04:00
Dawson Hessler f4d6fc2b4b Merge branch 'master' of https://github.com/funkemunky/AntiVPN 2023-10-30 10:00:12 -04:00
Dawson Hessler d461b5945b Update maven.yml 2023-10-30 09:59:50 -04:00
Dawson c6303ec1b2 Merge pull request #44 from funkemunky/funkemunky-patch-1
Updating build action to run on pull request
2023-10-30 09:57:55 -04:00
Dawson Hessler ca8fb24134 Caching maven repos properly 2023-10-30 09:54:58 -04:00
Dawson 5e37d2c371 Updating to run on pull request 2023-10-30 09:50:47 -04:00
Dawson Hessler 48c6dd63ee Revert "Merge pull request #35 from C0D3-M4513R/patch-1"
This reverts commit db1cdad4e1, reversing
changes made to 9f66570088.
2023-10-30 09:48:04 -04:00
C0D3 M4513R 50e7059597 Add null checks to ip check on login
Supersedes: #41
Fixes: #39
2023-10-18 05:57:22 +02:00
C0D3 M4513R 464b02f416 Fix PR #35 2023-10-18 05:45:27 +02:00
Dawson db1cdad4e1 Merge pull request #35 from C0D3-M4513R/patch-1 2023-10-17 18:58:31 -04:00
Dawson 9f66570088 Merge pull request #37 from C0D3-M4513R/command-suggestion 2023-10-17 18:57:47 -04:00
Dawson 5f0b2796b3 Merge pull request #40 from alexkarezin/master 2023-10-17 18:56:42 -04:00
Alex Karezin be5eb4e953 Update README.md by adding a link to repository map
Adding a link to the high-level diagrams including module, library dependency and others (https://sourcespy.com/github/funkemunkyantivpn/). Built directly from source and updated on schedule. Intended to simplify developer's introduction to the project.

In the spirit of transparency - I am the author of the diagrams. Hope contributors find it useful.
2023-07-31 14:43:20 -04:00
C0D3 M4513R dde81b0495 Bump version 2023-07-14 13:35:50 +02:00
C0D3 M4513R cbc00b79e2 Add command suggestion for empty args 2023-07-14 13:31:36 +02:00
C0D3 M4513R 3b2a463e58 Update PlanCommand.java 2023-07-14 13:17:47 +02:00
Dawson Hessler 96e48594d8 Fixing velocity loading issues 2023-07-12 08:45:39 -04:00
Dawson Hessler c1ab71c7ed Merge branch 'master' of https://github.com/funkemunky/AntiVPN 2023-07-06 20:26:07 -04:00
Dawson Hessler 4bda24f10c Bump to 1.9.0 2023-07-06 20:26:02 -04:00
Dawson 259cff4402 Merge pull request #32 from AlexProgrammerDE/patch-1
Remove unused import
2023-07-06 20:15:51 -04:00
Dawson Hessler c54e90dca1 Removing usages of System.out.print 2023-07-06 20:13:47 -04:00
Alex 4f1e3848de Remove unused import 2023-07-04 17:30:39 +02:00
Dawson 1606ad192e Working on spongepowered version of plugin 2023-05-25 10:24:42 -04:00
Dawson Hessler 40308869c0 1.8.4 Added cache for logins for faster response 2023-05-23 08:09:41 -04:00
Dawson Hessler 6959f35d0c Fixing whitelist issues in bukkit and bungee 2023-04-18 06:45:28 -04:00
Dawson Hessler 21b6924cce Fixing error with inserted type mismatch in H2 and MySQL 2023-04-18 06:42:07 -04:00
Dawson Hessler 9c843cd061 Updating to 1.8.3.1
Turns out we accidentally already used the 1.8.3 version
2023-03-13 15:08:04 -04:00
Dawson Hessler 91a09f6940 Updating version to 1.8.3 2023-03-13 15:04:14 -04:00
Dawson Hessler 36b44200c4 Adding response expiry since I just realized it never expires 2023-03-13 15:00:39 -04:00
dependabot[bot] 903dd8e73e Bump snakeyaml from 1.30 to 2.0 in /Common
Bumps [snakeyaml](https://bitbucket.org/snakeyaml/snakeyaml) from 1.30 to 2.0.
- [Commits](https://bitbucket.org/snakeyaml/snakeyaml/branches/compare/snakeyaml-2.0..snakeyaml-1.30)

---
updated-dependencies:
- dependency-name: org.yaml:snakeyaml
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 19:31:59 +00:00
Dawson e6bc601372 Fixing compile bug 2023-02-28 14:31:40 -05:00
Dawson 9dbf0e8635 Merge branch 'master' of https://github.com/funkemunky/AntiVPN 2022-11-02 10:39:50 -04:00
Dawson dd1b6afbb7 Working on adding sponge support 2022-11-02 10:39:48 -04:00
Dawson Hessler 14e266b978 Fixing load issue with snakeyaml on 1.12+ servers 2022-09-02 09:34:47 -04:00
Dawson Hessler cc289f41ff Instead of deleting old files, make new one 2022-08-29 07:34:53 -04:00
Dawson Hessler bf5b81b750 1.8.2.1, fixed H2 and removed debug 2022-08-29 07:19:42 -04:00
Dawson a480f13302 Merge pull request #26 from funkemunky/reload-commmand
Shrunk jar file size, fixed errors, added database reload
2022-08-28 13:18:09 -04:00
Dawson Hessler 4a95b51350 Replaced incorrect SQLLite messaging with H2 2022-08-28 13:17:30 -04:00
Dawson Hessler 9dc312186b Shrunk jar file size, fixed errors, added database reload
- Fixed H2 database error on index creation when loading plugin by using dynamic library downloader/loader from Lucko's Helper.
- Shrunk jar file size extensively so it can be uploaded to Spigot directly.
- Updated h2database driver to 2.1.214 to patch vulnerability
- Updated mysql database driver to 8.0.30 to patch vulnerability
- Updated MongoDB java driver to 3.12.11.
2022-08-28 13:14:13 -04:00
Dawson 3f9a2100a9 Merge pull request #25 from funkemunky/reload-commmand
New /antivpn reload and Message Configuration
2022-08-28 12:14:35 -04:00
Dawson Hessler 4c82755935 Adding comment and added some default messages to help formatting on generation 2022-08-28 12:13:57 -04:00
Dawson Hessler 0048cf6b8c 1.8.2 2022-08-28 12:12:24 -04:00
Dawson Hessler 795c869fc0 Fixed reloading and adding of messages into config 2022-08-28 12:11:41 -04:00
Dawson Hessler 95a00a4d0a Adding ability to configure "no permission" message 2022-08-28 11:53:46 -04:00
Dawson Hessler a6f26d4ba7 Merge branch 'master' into reload-commmand 2022-08-28 11:42:58 -04:00
Dawson 7a0786e29f Shit 2022-08-24 11:43:29 -04:00
Dawson df4a14086b Updating workflow
- Now uploading alpha jars on workflow.
- Caching depends to make it run faster
2022-08-19 11:12:34 -04:00
Dawson f55fa88c2b Merge pull request #24 from funkemunky/dependabot/maven/Common/mysql-mysql-connector-java-8.0.28
Bump mysql-connector-java from 8.0.27 to 8.0.28 in /Common
2022-08-19 11:10:29 -04:00
Dawson 4f79522010 Fixing memory leak 2022-08-19 11:09:52 -04:00
Dawson Hessler 7654cca651 Adding reload command 2022-08-05 14:14:42 -04:00
Dawson Hessler e01cbf95f2 Fixing whitelist ip and uuid checking 2022-07-10 12:59:45 -04:00
Dawson Hessler db49d400a0 Fixing whitelist checking for users 2022-07-10 12:57:05 -04:00
dependabot[bot] b39cc3e19c Bump mysql-connector-java from 8.0.27 to 8.0.28 in /Common
Bumps [mysql-connector-java](https://github.com/mysql/mysql-connector-j) from 8.0.27 to 8.0.28.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.27...8.0.28)

---
updated-dependencies:
- dependency-name: mysql:mysql-connector-java
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-21 04:21:04 +00:00
Dawson ff25c75055 Update .gitignore 2022-06-17 13:05:52 -04:00
Dawson 733e797a17 Implemented /kaurivpn plan 2022-06-06 10:15:40 -04:00
Dawson 0c903794e5 Cleaning up, adding QueryResponse
- Putting API classes under its own package.
- Moved API calls from AntiVPN into new FunkemunkyAPI class.
- Added QueryResponse object and FunkemunkyAPI#getQueryResponse get grab plan information.
2022-06-06 09:32:48 -04:00
57 changed files with 1431 additions and 782 deletions
+34
View File
@@ -0,0 +1,34 @@
---
name: Bug report
about: Create a bug report that will allow us to fix any unexpected behavior
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**What instance are you running KauriVPN on?**
*Put an 'x' in the brackets to check it*
- [ ] Velocity
- [ ] Bukkit/Spigot
- [ ] Bungeecord
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea you would like added
title: "[FEATURE] "
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+14 -6
View File
@@ -1,20 +1,28 @@
on:
push:
branches: ["**"]
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK 17.0.2
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
java-version: 17.0
distribution: 'zulu'
cache: 'maven'
- name: Compile
run: mvn -B -Pclean install
run: mvn -B package --file pom.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload AntiVPN
uses: actions/upload-artifact@v4
with:
name: AntiVPN
path: Assembly/target/Assembly-*.jar
+3
View File
@@ -13,6 +13,9 @@ local.properties
.settings/
.loadpath
.recommenders
*.iml
.idea/
# External tool builders
.externalToolBuilders/
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Assembly</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.mongodb</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.mongodb</shadedPattern>
</relocation>
<relocation>
<pattern>org.bson</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.org.bson</shadedPattern>
</relocation>
<relocation>
<pattern>com.mysql</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.mysql</shadedPattern>
</relocation>
<relocation>
<pattern>com.moandjiezana</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.moandjiezana</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>cc.funkemunky.utils</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+5 -18
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,7 +21,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.5.2</version>
<executions>
<execution>
<phase>package</phase>
@@ -29,27 +29,14 @@
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.org.yaml.snakeyaml</shadedPattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.mongodb</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.mongodb</shadedPattern>
</relocation>
<relocation>
<pattern>org.bson</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.org.bson</shadedPattern>
</relocation>
<relocation>
<pattern>com.mysql</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.mysql</shadedPattern>
</relocation>
<relocation>
<pattern>com.moandjiezana</pattern>
<shadedPattern>dev.brighten.antivpn.utils.shaded.com.moandjiezana</shadedPattern>
<pattern>com.google.common</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.com.google.common</shadedPattern>
</relocation>
</relocations>
</configuration>
-96
View File
@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Bukkit</artifactId>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>8</source>
<target>8</target>
<compilerArgument>-XDignore.symbol.file</compilerArgument>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>dev.brighten.antivpn.bukkit.org.bstats</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.github.spigot</groupId>
<artifactId>1.13.2</artifactId>
<version>1.13.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.7.1.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>toml4j</artifactId>
<groupId>com.moandjiezana.toml</groupId>
</exclusion>
<exclusion>
<artifactId>mysql-connector-java</artifactId>
<groupId>mysql</groupId>
</exclusion>
<exclusion>
<artifactId>h2</artifactId>
<groupId>com.h2database</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>mongo-java-driver</artifactId>
<groupId>org.mongodb</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cc.funkemunky.utils</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+24 -16
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -16,7 +16,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.13.0</version>
<configuration>
<source>8</source>
<target>8</target>
@@ -26,22 +26,30 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<!-- Replace this with your package! -->
<shadedPattern>dev.brighten.antivpn.bukkit.org.bstats</shadedPattern>
</relocation>
</relocations>
</configuration>
<version>3.5.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<!-- Replace this with your package! -->
<shadedPattern>dev.brighten.antivpn.bukkit.org.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.com.google.common</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
@@ -61,15 +69,15 @@
<dependencies>
<dependency>
<groupId>org.github.spigot</groupId>
<artifactId>1.13.2</artifactId>
<version>1.13.2</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -16,8 +16,9 @@ public class BukkitCommandExecutor implements CommandExecutor {
private final CommandSender sender;
@Override
public void sendMessage(String message) {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
public void sendMessage(String message, Object... objects) {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&',
String.format(message, objects)));
}
@Override
@@ -1,25 +1,35 @@
package dev.brighten.antivpn.bukkit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.message.VpnString;
import dev.brighten.antivpn.web.objects.VPNResponse;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@SuppressWarnings("unchecked")
public class BukkitListener extends VPNExecutor implements Listener {
private final Cache<UUID, VPNResponse> responseCache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(2000)
.build();
private BukkitTask cacheResetTask;
@Override
public void registerListeners() {
BukkitPlugin.pluginInstance.getServer().getPluginManager()
@@ -27,41 +37,36 @@ public class BukkitListener extends VPNExecutor implements Listener {
}
@Override
public void runCacheReset() {
cacheResetTask = new BukkitRunnable() {
public void run() {
resetCache();
}
}.runTaskTimerAsynchronously(BukkitPlugin.pluginInstance, 24000, 24000); //Reset cache every 20 minutes
public void shutdown() {
HandlerList.unregisterAll(this);
threadExecutor.shutdown();
}
@Override
public void shutdown() {
if(cacheResetTask != null && !cacheResetTask.isCancelled()) cacheResetTask.cancel();
public void log(Level level, String log, Object... objects) {
Bukkit.getLogger().log(level, String.format(log, objects));
}
@Override
public void log(String log, Object... objects) {
Bukkit.getLogger().log(Level.INFO, String.format(log, objects));
log(Level.INFO, String.format(log, objects));
}
@Override
public void logException(String message, Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, message, ex);
}
@EventHandler
public void onJoin(final PlayerJoinEvent event) {
AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId())
.ifPresent(player -> {
AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> {
if(enabled) {
AntiVPN.getInstance().getExecutor().log("Enabled");
player.setAlertsEnabled(true);
player.sendMessage(AntiVPN.getInstance().getMessageHandler()
.getString("command-alerts-toggled")
.getFormattedMessage(new VpnString.Var<>("state", true)));
} else AntiVPN.getInstance().getExecutor().log("Not enabled");
});
});
.ifPresent(player -> AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> {
if(enabled) {
player.setAlertsEnabled(true);
player.sendMessage(AntiVPN.getInstance().getMessageHandler()
.getString("command-alerts-toggled")
.getFormattedMessage(new VpnString.Var<>("state", true)));
}
}));
}
@EventHandler
@@ -74,81 +79,153 @@ public class BukkitListener extends VPNExecutor implements Listener {
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return;
if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) {
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
if (cached != null && cached.isProxy()) {
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
event.setKickMessage(org.bukkit.ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getVpnConfig().getKickString()));
return;
}
}
final Player player = event.getPlayer();
checkIp(event.getAddress().getHostAddress(),
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
if(result.isSuccess()) {
//We need to run on main thread or kicking and running commands will cause errors
new BukkitRunnable() {
public void run() {
// If the countryList() size is zero, no need to check.
// Running country check first
if(AntiVPN.getInstance().getVpnConfig().countryList().size() > 0
// This bit of code will decide whether or not to kick the player
// If it contains the code and it is set to whitelist, it will not kick as they are equal
// and vise versa. However, if the contains does not match the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
//Using our built in kicking system if no commands are configured
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().size() == 0) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
// Kicking our player
//If the player is whitelisted, we don't want to kick them
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) {
log("UUID is whitelisted: %s",
event.getPlayer().getUniqueId().toString());
return;
}
//If the IP is whitelisted, we don't want to kick them
InetSocketAddress address = event.getPlayer().getAddress();
if (address != null){
InetAddress address1 = address.getAddress();
if (address1 != null && AntiVPN.getInstance().getExecutor()
.isWhitelisted(address1.getHostAddress())) {
log("IP is whitelisted: %s",
address1.getHostAddress());
return;
}
}
// If the countryList() size is zero, no need to check.
// Running country check first
if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
// This bit of code will decide whether or not to kick the player
// If it contains the code and it is set to whitelist, it will not kick as they are equal
// and vise versa. However, if the contains does not match the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
// Start "online" fix
// In case the response was so fast from API the player wouldn't be "online".
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
event.setKickMessage(ChatColor
.translateAlternateColorCodes('&',
kickReason
.replace("%player%", event.getPlayer().getName())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode())));
// End "online" fix
//Using our built in kicking system if no commands are configured
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
// Kicking our player
new BukkitRunnable() {
public void run() {
event.getPlayer().kickPlayer(ChatColor
.translateAlternateColorCodes('&',
kickReason
.replace("%player%", event.getPlayer().getName())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode())));
} else {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
cmd.replace("%player%", event.getPlayer().getName())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()));
// Runs our command from console
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
}
}
} else if(result.isProxy()) {
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect())
}.runTask(BukkitPlugin.pluginInstance);
} else {
final String playerName = event.getPlayer().getName();
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
.addAction(event.getPlayer().getUniqueId(), () -> {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
cmd.replace("%player%", playerName)
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()));
// Runs our command from console
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
}
});
}
} else if(result.isProxy()) {
// Start "online" fix
// In case the response was so fast from API the player wouldn't be "online".
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
event.setKickMessage(ChatColor
.translateAlternateColorCodes('&',
AntiVPN.getInstance().getVpnConfig().getKickString()
.replace("%player%", event.getPlayer().getName())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode())));
// End "online" fix
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
new BukkitRunnable() {
public void run() {
player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getVpnConfig().getKickString()));
Bukkit.getLogger().info(event.getPlayer().getName()
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
//Ensuring the user wishes to alert to staff
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage()
.replace("%player%", event.getPlayer().getName())
.replace("%reason%", result.getMethod())
.replace("%country%", result.getCountryName())
.replace("%city%", result.getCity())));
//In case the user wants to run their own commands instead of using the built in kicking
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
ChatColor.translateAlternateColorCodes('&',
command.replace("%player%",
event.getPlayer().getName())));
}
}
AntiVPN.getInstance().detections++;
}
}.runTask(BukkitPlugin.pluginInstance);
}
}.runTask(BukkitPlugin.pluginInstance);
log(Level.INFO, event.getPlayer().getName()
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
//Ensuring the user wishes to alert to staff
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage()
.replace("%player%", event.getPlayer().getName())
.replace("%reason%", result.getMethod())
.replace("%country%", result.getCountryName())
.replace("%city%", result.getCity())));
//In case the user wants to run their own commands instead of using the built in kicking
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
String playerName = event.getPlayer().getName();
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
.addAction(event.getPlayer().getUniqueId(), () -> {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
ChatColor.translateAlternateColorCodes('&',
command.replace("%player%",
playerName)));
}
});
}
AntiVPN.getInstance().detections++;
}
} else {
Bukkit.getLogger()
.log(Level.WARNING,
log(Level.WARNING,
"The API query was not a success! " +
"You may need to upgrade your license on https://funkemunky.cc/shop");
}
AntiVPN.getInstance().checked++;
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId());
}
}
@@ -10,7 +10,7 @@ import java.util.stream.Collectors;
public class BukkitPlayerExecutor implements PlayerExecutor {
private final Map<UUID, BukkitPlayer> cachedPlayers = new WeakHashMap<>();
private final Map<UUID, BukkitPlayer> cachedPlayers = new HashMap<>();
@Override
public Optional<APIPlayer> getPlayer(String name) {
@@ -34,6 +34,11 @@ public class BukkitPlayerExecutor implements PlayerExecutor {
return Optional.of(cachedPlayers.computeIfAbsent(player.getUniqueId(), k -> new BukkitPlayer(player)));
}
@Override
public void unloadPlayer(UUID uuid) {
cachedPlayers.remove(uuid);
}
@Override
public List<APIPlayer> getOnlinePlayers() {
@@ -3,7 +3,7 @@ package dev.brighten.antivpn.bukkit;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.bukkit.command.BukkitCommand;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.utils.ConfigDefault;
import lombok.Getter;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SingleLineChart;
import org.bukkit.Bukkit;
@@ -22,8 +22,12 @@ public class BukkitPlugin extends JavaPlugin {
public static BukkitPlugin pluginInstance;
private SimpleCommandMap commandMap;
private List<org.bukkit.command.Command> registeredCommands = new ArrayList<>();
private final List<org.bukkit.command.Command> registeredCommands = new ArrayList<>();
@Getter
private SingleLineChart vpnDetections, ipsChecked;
@Getter
private PlayerCommandRunner playerCommandRunner;
public void onEnable() {
pluginInstance = this;
@@ -31,6 +35,9 @@ public class BukkitPlugin extends JavaPlugin {
Bukkit.getLogger().info("Starting AntiVPN services...");
AntiVPN.start(new BukkitListener(), new BukkitPlayerExecutor(), getDataFolder());
playerCommandRunner = new PlayerCommandRunner();
playerCommandRunner.start();
// Loading our bStats metrics to be pushed to https://bstats.org
if(AntiVPN.getInstance().getVpnConfig().metrics()) {
Bukkit.getLogger().info("Starting bStats metrics...");
@@ -77,12 +84,15 @@ public class BukkitPlugin extends JavaPlugin {
(vpnString.getDefaultMessage(), "messages." + vpnString.getKey(), BukkitPlugin.pluginInstance)
.get());
AntiVPN.getInstance().getMessageHandler().reloadStrings();*/
reloadConfig();
}
@Override
public void onDisable() {
Bukkit.getLogger().info("Stopping plugin services...");
AntiVPN.getInstance().stop();
playerCommandRunner.stop();
Bukkit.getLogger().info("Unregistering commands...");
try {
@@ -0,0 +1,61 @@
package dev.brighten.antivpn.bukkit;
import dev.brighten.antivpn.utils.MiscUtils;
import lombok.Data;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class PlayerCommandRunner {
private final ScheduledExecutorService executorService;
private final Queue<PlayerAction> playerActions = new ArrayBlockingQueue<>(10000);
public PlayerCommandRunner() {
executorService = Executors.newSingleThreadScheduledExecutor(
MiscUtils.createThreadFactory("AntiVPN:PlayerCommandRunner")
);
}
void start() {
executorService.scheduleAtFixedRate(() -> {
long currentTime = System.currentTimeMillis();
while(!playerActions.isEmpty()) {
PlayerAction action = playerActions.peek();
if(action == null) continue;
if(currentTime - action.start > 2000L || Bukkit.getPlayer(action.getUuid()) != null) {
new BukkitRunnable() {
public void run() {
action.getAction().run();
}
}.runTask(BukkitPlugin.pluginInstance);
playerActions.poll();
}
}
}, 1000, 100, TimeUnit.MILLISECONDS);
}
void stop() {
executorService.shutdown();
playerActions.clear();
}
void addAction(UUID uuid, Runnable action) {
playerActions.add(new PlayerAction(uuid, System.currentTimeMillis(), action));
}
@Data
static class PlayerAction {
private final UUID uuid;
private final long start;
private final Runnable action;
}
}
@@ -1,5 +1,6 @@
package dev.brighten.antivpn.bukkit.command;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.bukkit.BukkitCommandExecutor;
import dev.brighten.antivpn.command.Command;
import lombok.val;
@@ -41,7 +42,8 @@ public class BukkitCommand extends org.bukkit.command.Command {
public boolean execute(CommandSender sender, String s, String[] args) {
if(!sender.hasPermission("antivpn.command.*")
&& !sender.hasPermission(command.permission())) {
sender.sendMessage(ChatColor.RED + "No permission.");
sender.sendMessage(ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage()));
return true;
}
@@ -53,7 +55,8 @@ public class BukkitCommand extends org.bukkit.command.Command {
.anyMatch(alias -> alias.equalsIgnoreCase(args[0]))) {
if(!sender.hasPermission("antivpn.command.*")
&& !sender.hasPermission(child.permission())) {
sender.sendMessage(ChatColor.RED + "No permission.");
sender.sendMessage(ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage()));
return true;
}
-96
View File
@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Bungee</artifactId>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>8</source>
<target>8</target>
<compilerArgument>-XDignore.symbol.file</compilerArgument>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>dev.brighten.antivpn.bungee.org.bstats</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.7.1.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>toml4j</artifactId>
<groupId>com.moandjiezana.toml</groupId>
</exclusion>
<exclusion>
<artifactId>mysql-connector-java</artifactId>
<groupId>mysql</groupId>
</exclusion>
<exclusion>
<artifactId>h2</artifactId>
<groupId>com.h2database</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>mongo-java-driver</artifactId>
<groupId>org.mongodb</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.github.bungee</groupId>
<artifactId>BungeeCord-1.8</artifactId>
<version>1.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cc.funkemunky.utils</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+12 -4
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -16,7 +16,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.13.0</version>
<configuration>
<source>8</source>
<target>8</target>
@@ -26,7 +26,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<version>3.5.2</version>
<configuration>
<relocations>
<relocation>
@@ -34,6 +34,14 @@
<!-- Replace this with your package! -->
<shadedPattern>dev.brighten.antivpn.bungee.org.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.google</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.com.google</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -63,7 +71,7 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -1,16 +1,23 @@
package dev.brighten.antivpn.bungee;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.web.objects.VPNResponse;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.PreLoginEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@@ -18,18 +25,17 @@ public class BungeeListener extends VPNExecutor implements Listener {
private ScheduledTask cacheResetTask;
private final Cache<UUID, VPNResponse> responseCache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(2000)
.build();
@Override
public void registerListeners() {
BungeePlugin.pluginInstance.getProxy().getPluginManager()
.registerListener(BungeePlugin.pluginInstance, this);
}
@Override
public void runCacheReset() {
cacheResetTask = BungeePlugin.pluginInstance.getProxy().getScheduler().schedule(BungeePlugin.pluginInstance,
this::resetCache, 20, 20, TimeUnit.MINUTES);
}
@Override
public void shutdown() {
if(cacheResetTask != null) {
@@ -41,33 +47,71 @@ public class BungeeListener extends VPNExecutor implements Listener {
}
@Override
public void log(String log, Object... objects) {
public void log(Level level, String log, Object... objects) {
BungeeCord.getInstance().getLogger().log(Level.INFO, String.format(log, objects));
}
@EventHandler
@Override
public void log(String log, Object... objects) {
log(Level.INFO, String.format(log, objects));
}
@Override
public void logException(String message, Exception ex) {
BungeeCord.getInstance().getLogger().log(Level.SEVERE, message, ex);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onListener(final PreLoginEvent event) {
if(!responseCache.asMap().containsKey(event.getConnection().getUniqueId())) return;
VPNResponse cached = responseCache.getIfPresent(event.getConnection().getUniqueId());
if(cached != null && cached.isProxy()) {
event.setCancelled(true);
event.setCancelReason(TextComponent.fromLegacyText(ChatColor
.translateAlternateColorCodes('&',
AntiVPN.getInstance().getVpnConfig().getKickString())));
AntiVPN.getInstance().getExecutor().log(Level.INFO,
"%s was kicked from pre-login proxy cache.",
event.getConnection().getName());
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onListener(final PostLoginEvent event) {
if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getAddress().getAddress()
.getHostAddress())
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return;
checkIp(event.getPlayer().getAddress().getAddress().getHostAddress(),
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
if(result.isSuccess()) {
// If the countryList() size is zero, no need to check.
// Running country check first
if(AntiVPN.getInstance().getVpnConfig().countryList().size() > 0
//If the player is whitelisted, we don't want to kick them
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) {
AntiVPN.getInstance().getExecutor().log("UUID is whitelisted: %s",
event.getPlayer().getUniqueId().toString());
return;
}
//If the IP is whitelisted, we don't want to kick them
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getAddress().getAddress()
.getHostAddress())) {
AntiVPN.getInstance().getExecutor().log("IP is whitelisted: %s",
event.getPlayer().getAddress().getAddress().getHostAddress());
return;
}
responseCache.put(event.getPlayer().getUniqueId(), result);
if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
// This bit of code will decide whether or not to kick the player
// If it contains the code and it is set to whitelist, it will not kick as they are equal
// and vise versa. However, if the contains does not match the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode()) != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
//Using our built in kicking system if no commands are configured
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().size() == 0) {
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
// Kicking our player
@@ -127,4 +171,9 @@ public class BungeeListener extends VPNExecutor implements Listener {
AntiVPN.getInstance().checked++;
});
}
@EventHandler
public void onLeave(PlayerDisconnectEvent event) {
AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId());
}
}
@@ -10,7 +10,7 @@ import java.util.stream.Collectors;
public class BungeePlayerExecutor implements PlayerExecutor {
private final Map<ProxiedPlayer, BungeePlayer> cachedPlayers = new WeakHashMap<>();
private final Map<UUID, BungeePlayer> cachedPlayers = new HashMap<>();
@Override
public Optional<APIPlayer> getPlayer(String name) {
@@ -18,7 +18,7 @@ public class BungeePlayerExecutor implements PlayerExecutor {
if(player == null) return Optional.empty();
return Optional.of(cachedPlayers.computeIfAbsent(player, BungeePlayer::new));
return Optional.of(cachedPlayers.computeIfAbsent(player.getUniqueId(), key -> new BungeePlayer(player)));
}
@Override
@@ -27,13 +27,18 @@ public class BungeePlayerExecutor implements PlayerExecutor {
if(player == null) return Optional.empty();
return Optional.of(cachedPlayers.computeIfAbsent(player, BungeePlayer::new));
return Optional.of(cachedPlayers.computeIfAbsent(uuid, key -> new BungeePlayer(player)));
}
@Override
public void unloadPlayer(UUID uuid) {
this.cachedPlayers.remove(uuid);
}
@Override
public List<APIPlayer> getOnlinePlayers() {
return BungeeCord.getInstance().getPlayers().stream()
.map(pl -> cachedPlayers.computeIfAbsent(pl, BungeePlayer::new))
.map(pl -> cachedPlayers.computeIfAbsent(pl.getUniqueId(), key -> new BungeePlayer(pl)))
.collect(Collectors.toList());
}
}
@@ -3,7 +3,6 @@ package dev.brighten.antivpn.bungee;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.bungee.command.BungeeCommand;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.utils.ConfigDefault;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
@@ -44,11 +43,6 @@ public class BungeePlugin extends Plugin {
for (Command command : AntiVPN.getInstance().getCommands()) {
BungeeCord.getInstance().getPluginManager().registerCommand(pluginInstance, new BungeeCommand(command));
}
BungeeCord.getInstance().getLogger().info("Getting strings...");
AntiVPN.getInstance().getMessageHandler().initStrings(vpnString -> new ConfigDefault<>
(vpnString.getDefaultMessage(), "messages." + vpnString.getKey(), AntiVPN.getInstance())
.get());
}
@Override
@@ -1,10 +1,9 @@
package dev.brighten.antivpn.bungee.command;
import dev.brighten.antivpn.AntiVPN;
import lombok.val;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
@@ -14,9 +13,6 @@ import java.util.stream.IntStream;
public class BungeeCommand extends Command implements TabExecutor {
private static final BaseComponent[] noPermission = new ComponentBuilder("No permission").color(ChatColor.RED)
.create();
private final dev.brighten.antivpn.command.Command command;
public BungeeCommand(dev.brighten.antivpn.command.Command command) {
super(command.name(), command.permission(), command.aliases());
@@ -28,7 +24,8 @@ public class BungeeCommand extends Command implements TabExecutor {
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("antivpn.command.*")
&& !sender.hasPermission(command.permission())) {
sender.sendMessage(noPermission);
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage())));
return;
}
@@ -40,7 +37,8 @@ public class BungeeCommand extends Command implements TabExecutor {
.anyMatch(alias -> alias.equalsIgnoreCase(args[0]))) {
if(!sender.hasPermission("antivpn.command.*")
&& !sender.hasPermission(child.permission())) {
sender.sendMessage(noPermission);
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage())));
return;
}
@@ -17,9 +17,9 @@ public class BungeeCommandExecutor implements CommandExecutor {
private final CommandSender sender;
@Override
public void sendMessage(String message) {
public void sendMessage(String message, Object... objects) {
sender.sendMessage(TextComponent.fromLegacyText(ChatColor
.translateAlternateColorCodes('&', message)));
.translateAlternateColorCodes('&', String.format(message, objects))));
}
@Override
+50 -16
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,13 +21,50 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.13.0</version>
<configuration>
<source>8</source>
<target>8</target>
<compilerArgument>-XDignore.symbol.file</compilerArgument>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.com.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>org.h2</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.h2</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
@@ -46,34 +83,31 @@
<dependencies>
<dependency>
<groupId>com.moandjiezana.toml</groupId>
<artifactId>toml4j</artifactId>
<version>0.7.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
<type>jar</type>
<scope>compile</scope>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.210</version>
<version>2.2.224</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.30</version>
<version>2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.10</version>
<version>3.12.14</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -12,13 +12,9 @@ import dev.brighten.antivpn.database.sql.MySqlVPN;
import dev.brighten.antivpn.message.MessageHandler;
import dev.brighten.antivpn.utils.ConfigDefault;
import dev.brighten.antivpn.utils.MiscUtils;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.utils.config.Configuration;
import dev.brighten.antivpn.utils.config.ConfigurationProvider;
import dev.brighten.antivpn.utils.config.YamlConfiguration;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.utils.json.JSONObject;
import dev.brighten.antivpn.utils.json.JsonReader;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@@ -54,6 +50,7 @@ public class AntiVPN {
INSTANCE.pluginFolder = pluginFolder;
INSTANCE.executor = executor;
INSTANCE.playerExecutor = playerExecutor;
try {
File configFile = new File(pluginFolder, "config.yml");
if(!configFile.exists()){
@@ -119,6 +116,7 @@ public class AntiVPN {
AntiVPN.getInstance().getMessageHandler().initStrings(vpnString -> new ConfigDefault<>
(vpnString.getDefaultMessage(), "messages." + vpnString.getKey(), AntiVPN.getInstance())
.get());
AntiVPN.getInstance().getMessageHandler().reloadStrings();
}
public InputStream getResource(String filename) {
@@ -145,6 +143,40 @@ public class AntiVPN {
if(database != null) database.shutdown();
}
public void reloadDatabase() {
database.shutdown();
switch(AntiVPN.getInstance().getVpnConfig().getDatabaseType().toLowerCase()) {
case "h2":
case "local":
case "flatfile": {
AntiVPN.getInstance().getExecutor().log("Using databaseType H2...");
INSTANCE.database = new H2VPN();
INSTANCE.database.init();
break;
}
case "mysql":
case "sql":{
AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL...");
INSTANCE.database = new MySqlVPN();
INSTANCE.database.init();
break;
}
case "mongo":
case "mongodb":
case "mongod": {
INSTANCE.database = new MongoVPN();
INSTANCE.database.init();
break;
}
default: {
AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.vpnConfig.getDatabaseType() + "\". " +
"Options: [MySQL]");
break;
}
}
}
public static AntiVPN getInstance() {
assert INSTANCE != null: "AntiVPN has not been initialized!";
@@ -160,13 +192,14 @@ public class AntiVPN {
}
}
public static VPNResponse getVPNResponse(String ip, String license, boolean cachedResults /* faster if set to true*/)
throws JSONException, IOException {
JSONObject result = JsonReader.readJsonFromUrl(String
.format("https://funkemunky.cc/vpn?ip=%s&license=%s&cache=%s",
ip, license.length() == 0 ? "none" : license, cachedResults));
public void reloadConfig() {
try {
return VPNResponse.fromJson(result);
config = ConfigurationProvider.getProvider(YamlConfiguration.class)
.load(new File(pluginFolder.getPath() + File.separator + "config.yml"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void registerCommands() {
@@ -10,5 +10,7 @@ public interface PlayerExecutor {
Optional<APIPlayer> getPlayer(UUID uuid);
void unloadPlayer(UUID uuid);
List<APIPlayer> getOnlinePlayers();
}
@@ -1,101 +1,100 @@
package dev.brighten.antivpn.api;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.utils.EvictingMap;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.web.FunkemunkyAPI;
import dev.brighten.antivpn.web.objects.VPNResponse;
import lombok.Getter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.logging.Level;
public abstract class VPNExecutor {
public static ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
public static ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2);
public static final Map<String, VPNResponse> responseCache = new EvictingMap<>(5000);
@Getter
private final Set<UUID> whitelisted = Collections.synchronizedSet(new HashSet<>());
@Getter
private final Set<String> whitelistedIps = Collections.synchronizedSet(new HashSet<>());
private final Cache<String, VPNResponse> responseCache = CacheBuilder.newBuilder()
.expireAfterWrite(20, TimeUnit.MINUTES)
.maximumSize(4000)
.build();
public abstract void registerListeners();
public abstract void runCacheReset();
public void resetCache() {
responseCache.clear();
}
public abstract void shutdown();
public abstract void log(Level level, String log, Object... objects);
public abstract void log(String log, Object... objects);
public abstract void logException(String message, Exception ex);
public void logException(Exception ex) {
logException("An exception occurred: " + ex.getMessage(), ex);
}
public boolean isWhitelisted(UUID uuid) {
if(AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) {
return AntiVPN.getInstance().getDatabase().isWhitelisted(uuid);
}
return whitelisted.contains(uuid);
}
public boolean isWhitelisted(String ip) {
if(AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) {
return AntiVPN.getInstance().getDatabase().isWhitelisted(ip);
}
return whitelistedIps.contains(ip);
}
public void checkIp(String ip, boolean cachedResults, Consumer<VPNResponse> result) {
threadExecutor.execute(() -> result.accept(responseCache.compute(ip, (key, val) -> {
if(val == null) {
Optional<VPNResponse> cachedRes = AntiVPN.getInstance().getDatabase().getStoredResponse(ip);
if(cachedRes.isPresent()) return cachedRes.get();
else {
try {
VPNResponse response = AntiVPN
.getVPNResponse(ip, AntiVPN.getInstance().getVpnConfig().getLicense(), cachedResults);
if(response.isSuccess()) {
AntiVPN.getInstance().getDatabase().cacheResponse(response);
} else {
log("Query to VPN API failed! Reason: " + response.getFailureReason());
}
return response;
} catch (JSONException | IOException e) {
log("Query to VPN API failed! Reason: Java Exception");
e.printStackTrace();
}
threadExecutor.execute(() -> {
if(cachedResults) {
try {
result.accept(responseCache.get(ip, () -> checkIp(ip)));
} catch (ExecutionException e) {
log("Failed to process checkIp() method! Reason: " + e.getMessage());
result.accept(VPNResponse.FAILED_RESPONSE);
}
} else {
result.accept(checkIp(ip));
}
return val;
})));
}
public VPNResponse checkIp(String ip, boolean cachedResults) {
return responseCache.compute(ip, (key, val) -> {
if(val == null) {
Optional<VPNResponse> cachedRes = AntiVPN.getInstance().getDatabase().getStoredResponse(ip);
if(cachedRes.isPresent()) return cachedRes.get();
else {
try {
VPNResponse response = AntiVPN
.getVPNResponse(ip, AntiVPN.getInstance().getVpnConfig().getLicense(), cachedResults);
if(response.isSuccess()) {
threadExecutor.execute(() -> AntiVPN.getInstance().getDatabase().cacheResponse(response));
} else {
log("Query to VPN API failed! Reason: " + response.getFailureReason());
}
return response;
} catch (JSONException | IOException e) {
log("Query to VPN API failed! Reason: Java Exception");
e.printStackTrace();
}
}
}
return val;
});
}
public VPNResponse checkIp(String ip) {
Optional<VPNResponse> cachedRes = AntiVPN.getInstance().getDatabase().getStoredResponse(ip);
if(cachedRes.isPresent()) {
return cachedRes.get();
}
else {
try {
VPNResponse response = FunkemunkyAPI
.getVPNResponse(ip, AntiVPN.getInstance().getVpnConfig().getLicense(), true);
if (response.isSuccess()) {
AntiVPN.getInstance().getDatabase().cacheResponse(response);
} else {
log("Query to VPN API failed! Reason: " + response.getFailureReason());
}
return response;
} catch (JSONException | IOException e) {
log("Query to VPN API failed! Reason: " + e.getMessage());
return VPNResponse.FAILED_RESPONSE;
}
}
}
}
@@ -6,7 +6,7 @@ import java.util.Optional;
public interface CommandExecutor {
void sendMessage(String message);
void sendMessage(String message, Object... objects);
boolean hasPermission(String permission);
Optional<APIPlayer> getPlayer();
boolean isPlayer();
@@ -45,7 +45,7 @@ public class AntiVPNCommand extends Command {
@Override
public Command[] children() {
return new Command[] {new LookupCommand(), new AllowlistCommand(), new AlertsCommand(),
new ClearCacheCommand()};
new ClearCacheCommand(), new PlanCommand(), new ReloadCommand()};
}
@Override
@@ -1,7 +1,6 @@
package dev.brighten.antivpn.command.impl;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.command.CommandExecutor;
@@ -47,7 +46,6 @@ public class ClearCacheCommand extends Command {
@Override
public String execute(CommandExecutor executor, String[] args) {
AntiVPN.getInstance().getDatabase().clearResponses();
VPNExecutor.responseCache.clear();
return "&aCleared all cached API response information!";
}
@@ -67,13 +67,13 @@ public class LookupCommand extends Command {
executor.sendMessage(StringUtil.line("&8"));
executor.sendMessage("&6&l" + player.get().getName() + "&7&l's Connection Information");
executor.sendMessage("");
executor.sendMessage(String.format("&e%s&8: &f%s", "Proxy", result.isProxy()
? "&a" + result.getMethod() : "&cNo"));
executor.sendMessage(String.format("&e%s&8: &f%s", "ISP", result.getIsp()));
executor.sendMessage(String.format("&e%s&8: &f%s", "Country", result.getCountryName()));
executor.sendMessage(String.format("&e%s&8: &f%s", "City", result.getCity()));
executor.sendMessage(String.format("&e%s&8: &f%s", "Coordinates", result.getLatitude()
+ "&7/&f" + result.getLongitude()));
executor.sendMessage("&e%s&8: &f%s", "Proxy", result.isProxy()
? "&a" + result.getMethod() : "&cNo");
executor.sendMessage("&e%s&8: &f%s", "ISP", result.getIsp());
executor.sendMessage("&e%s&8: &f%s", "Country", result.getCountryName());
executor.sendMessage("&e%s&8: &f%s", "City", result.getCity());
executor.sendMessage("&e%s&8: &f%s", "Coordinates", result.getLatitude()
+ "&7/&f" + result.getLongitude());
executor.sendMessage(StringUtil.line("&8"));
}
});
@@ -0,0 +1,101 @@
package dev.brighten.antivpn.command.impl;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.command.CommandExecutor;
import dev.brighten.antivpn.utils.StringUtil;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.web.FunkemunkyAPI;
import dev.brighten.antivpn.web.objects.QueryResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class PlanCommand extends Command {
@Override
public String permission() {
return "antivpn.command.plan";
}
@Override
public String name() {
return "plan";
}
@Override
public String[] aliases() {
return new String[] {"queries", "query"};
}
@Override
public String description() {
return "Info related to KauriVPN Plan";
}
@Override
public String usage() {
return "";
}
@Override
public String parent() {
return "antivpn";
}
@Override
public Command[] children() {
return new Command[0];
}
@Override
public String execute(CommandExecutor executor, String[] args) {
VPNExecutor.threadExecutor.execute(() -> {
QueryResponse result;
try {
if(AntiVPN.getInstance().getVpnConfig().getLicense().isEmpty()) {
result = FunkemunkyAPI.getQueryResponse();
} else {
result = FunkemunkyAPI.getQueryResponse(AntiVPN.getInstance().getVpnConfig().getLicense());
if(!result.isValidPlan()) {
executor.sendMessage("&cThe license &f%s &cis not a valid license, " +
"checking your Free plan information...",
AntiVPN.getInstance().getVpnConfig().getLicense());
result = FunkemunkyAPI.getQueryResponse();
}
}
String plan = result.getPlanType();
if(plan.equals("IP")) plan+= " (Free)";
String queryMax = result.getQueriesMax() == Long.MAX_VALUE
? "Unlimited" : String.valueOf(result.getQueriesMax());
executor.sendMessage(StringUtil.line("&8"));
executor.sendMessage("&6&lKauriVPN Plan Information");
executor.sendMessage("");
executor.sendMessage("&e%s&8: &f%s", "Plan", plan);
executor.sendMessage("&e%s&8: &f%s&7/&f%s", "Queries Used",
result.getQueries(), queryMax);
executor.sendMessage(StringUtil.line("&8"));
} catch(JSONException e) {
AntiVPN.getInstance().getExecutor().logException(e);
executor.sendMessage("&cThere was a JSONException thrown while looking up your query " +
"information. Check console for more details.");
} catch (IOException e) {
AntiVPN.getInstance().getExecutor().logException(e);
executor.sendMessage("&cThere was a IOException thrown while looking up your query " +
"information. Check console for more details.");
}
});
return "&7Looking up your query information...";
}
@Override
public List<String> tabComplete(CommandExecutor executor, String alias, String[] args) {
return Collections.emptyList();
}
}
@@ -0,0 +1,65 @@
package dev.brighten.antivpn.command.impl;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.command.CommandExecutor;
import java.util.Collections;
import java.util.List;
public class ReloadCommand extends Command {
@Override
public String permission() {
return "antivpn.command.reload";
}
@Override
public String name() {
return "reload";
}
@Override
public String[] aliases() {
return new String[0];
}
@Override
public String description() {
return "Reload the plugin";
}
@Override
public String usage() {
return "";
}
@Override
public String parent() {
return "antivpn";
}
@Override
public Command[] children() {
return new Command[0];
}
@Override
public String execute(CommandExecutor executor, String[] args) {
// Loading changes from the config.yml
AntiVPN.getInstance().reloadConfig();
// Updating the cache of these values in VPNConfig
AntiVPN.getInstance().getVpnConfig().update();
AntiVPN.getInstance().getMessageHandler().reloadStrings();
AntiVPN.getInstance().reloadDatabase();
return AntiVPN.getInstance().getMessageHandler().getString("command-reload-complete").getMessage();
}
@Override
public List<String> tabComplete(CommandExecutor executor, String alias, String[] args) {
return Collections.emptyList();
}
}
@@ -1,6 +1,6 @@
package dev.brighten.antivpn.database;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.web.objects.VPNResponse;
import java.util.List;
import java.util.Optional;
@@ -12,6 +12,8 @@ public interface VPNDatabase {
void cacheResponse(VPNResponse toCache);
void deleteResponse(String ip);
boolean isWhitelisted(UUID uuid);
boolean isWhitelisted(String ip);
@@ -5,7 +5,7 @@ import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.database.VPNDatabase;
import dev.brighten.antivpn.database.sql.utils.MySQL;
import dev.brighten.antivpn.database.sql.utils.Query;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.web.objects.VPNResponse;
import lombok.SneakyThrows;
import java.sql.ResultSet;
@@ -20,34 +20,20 @@ import java.util.function.Consumer;
public class H2VPN implements VPNDatabase {
private Thread whitelistedThread;
public H2VPN() {
whitelistedThread = new Thread(() -> {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
// Updating from database
if (AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) {
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return;
whitelistedThread.start();
//Refreshing whitelisted players
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
//Refreshing whitlisted IPs
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}, 2, 30, TimeUnit.SECONDS);
}
@Override
@@ -65,7 +51,12 @@ public class H2VPN implements VPNDatabase {
rs.getString("method"), rs.getString("isp"), "N/A",
rs.getBoolean("proxy"), rs.getBoolean("cached"), true,
rs.getDouble("latitude"), rs.getDouble("longitude"),
System.currentTimeMillis(), -1);
rs.getTimestamp("inserted").getTime(), -1);
if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) {
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
return Optional.empty();
}
return Optional.of(response);
}
} catch (SQLException throwables) {
@@ -98,6 +89,14 @@ public class H2VPN implements VPNDatabase {
.append(toCache.getLatitude()).append(toCache.getLongitude()).execute();
}
@Override
public void deleteResponse(String ip) {
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
return;
Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute();
}
@SneakyThrows
@Override
public boolean isWhitelisted(UUID uuid) {
@@ -258,11 +257,11 @@ public class H2VPN implements VPNDatabase {
AntiVPN.getInstance().getExecutor().log("Creating indexes...");
try {
Query.prepare("create index `uuid_1` if not exists on `whitelisted` (`uuid`)").execute();
Query.prepare("create index `ip_1` if not exists on `responses` (`ip`)").execute();
Query.prepare("create index `proxy_1` if not exists on `responses` (`proxy`)").execute();
Query.prepare("create index `inserted_1` if not exists on `responses` (`inserted`)").execute();
Query.prepare("create index `ip_1` if not exists on `whitelisted-ips` (`ip`)").execute();
Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute();
Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute();
Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute();
Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute();
Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute();
} catch (Exception e) {
System.err.println("MySQL Excepton created" + e.getMessage());
}
@@ -7,26 +7,50 @@ import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Indexes;
import com.mongodb.client.model.UpdateOptions;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.database.VPNDatabase;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.web.objects.VPNResponse;
import org.bson.Document;
import org.bson.conversions.Bson;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class MongoVPN implements VPNDatabase {
private MongoCollection<Document> settingsDocument, cacheDocument;
private MongoClient client;
private MongoDatabase antivpnDatabase;
public MongoVPN() {
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) return;
//Refreshing whitelisted players
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
//Refreshing whitlisted IPs
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}, 2, 30, TimeUnit.SECONDS);
}
@Override
public Optional<VPNResponse> getStoredResponse(String ip) {
Document rdoc = cacheDocument.find(Filters.eq("ip", ip)).first();
if(rdoc != null) {
long lastUpdate = rdoc.get("lastAccess", 0L);
if(System.currentTimeMillis() - lastUpdate > TimeUnit.HOURS.toMillis(1)) {
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
return Optional.empty();
}
return Optional.of(VPNResponse.builder().asn(rdoc.getString("asn")).ip(ip)
.countryName(rdoc.getString("countryName"))
.countryCode(rdoc.getString("countryCode"))
@@ -39,6 +63,7 @@ public class MongoVPN implements VPNDatabase {
.success(true)
.latitude(rdoc.getDouble("latitude"))
.longitude(rdoc.getDouble("longitude"))
.lastAccess(rdoc.get("lastAccess", 0L))
.build());
}
return Optional.empty();
@@ -60,13 +85,20 @@ public class MongoVPN implements VPNDatabase {
rdoc.put("success", toCache.isSuccess());
rdoc.put("latitude", toCache.getLatitude());
rdoc.put("longitude", toCache.getLongitude());
rdoc.put("lastAccess", System.currentTimeMillis());
VPNExecutor.threadExecutor.execute(() -> {
cacheDocument.deleteMany(Filters.eq("ip", toCache.getIp()));
cacheDocument.insertOne(rdoc);
Bson update = new Document("$set", rdoc);
cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update,
new UpdateOptions().upsert(true));
});
}
@Override
public void deleteResponse(String ip) {
cacheDocument.deleteMany(Filters.eq("ip", ip));
}
@Override
public boolean isWhitelisted(UUID uuid) {
return settingsDocument
@@ -86,8 +118,10 @@ public class MongoVPN implements VPNDatabase {
if(whitelisted) {
Document wdoc = new Document("setting", "whitelist");
wdoc.put("uuid", uuid.toString());
AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid);
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
} else {
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters
.and(
Filters.eq("setting", "whitelist"),
@@ -98,10 +132,12 @@ public class MongoVPN implements VPNDatabase {
@Override
public void setWhitelisted(String ip, boolean whitelisted) {
if(whitelisted) {
Document wdoc = new Document("setting", "whitelist");
wdoc.put("ip", ip);
Document wdoc = new Document("setting", "whitelist").append("ip", ip);
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip);
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
} else {
AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip);
VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters
.and(
Filters.eq("setting", "whitelist"),
@@ -170,18 +206,20 @@ public class MongoVPN implements VPNDatabase {
@Override
public void init() {
if(AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL().length() > 0) { //URL
if(!AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL().isEmpty()) { //URL
ConnectionString cs = new ConnectionString(AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL());
MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(cs).build();
client = MongoClients.create(settings);
} else {
MongoClientSettings.Builder settingsBld = MongoClientSettings.builder().readPreference(ReadPreference.nearest())
.applyToClusterSettings(builder -> {
builder.hosts(Collections.singletonList(new ServerAddress(AntiVPN.getInstance().getVpnConfig().getIp(),
AntiVPN.getInstance().getVpnConfig().getPort())));
});
.applyToClusterSettings(builder -> builder.
hosts(Collections.singletonList(
new ServerAddress(
AntiVPN.getInstance().getVpnConfig().getIp(),
AntiVPN.getInstance().getVpnConfig().getPort())
)));
if(AntiVPN.getInstance().getVpnConfig().useDatabaseCreds()) {
settingsBld = settingsBld.credential(MongoCredential
settingsBld.credential(MongoCredential
.createCredential(AntiVPN.getInstance().getVpnConfig().getUsername(),
AntiVPN.getInstance().getVpnConfig().getDatabaseName(),
AntiVPN.getInstance().getVpnConfig().getPassword().toCharArray()));
@@ -189,7 +227,7 @@ public class MongoVPN implements VPNDatabase {
client = MongoClients.create(settingsBld.build());
}
antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName());
MongoDatabase antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName());
settingsDocument = antivpnDatabase.getCollection("settings");
if(settingsDocument.listIndexes().first() == null) {
@@ -5,7 +5,7 @@ import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.database.VPNDatabase;
import dev.brighten.antivpn.database.sql.utils.MySQL;
import dev.brighten.antivpn.database.sql.utils.Query;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.web.objects.VPNResponse;
import lombok.SneakyThrows;
import java.sql.ResultSet;
@@ -20,39 +20,25 @@ import java.util.function.Consumer;
public class MySqlVPN implements VPNDatabase {
private Thread whitelistedThread;
public MySqlVPN() {
whitelistedThread = new Thread(() -> {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
// Updating from database
if (AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) {
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> {
if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return;
whitelistedThread.start();
//Refreshing whitelisted players
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
//Refreshing whitlisted IPs
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}, 2, 30, TimeUnit.SECONDS);
}
@Override
public Optional<VPNResponse> getStoredResponse(String ip) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed())
if (isDisabled())
return Optional.empty();
ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery();
@@ -65,7 +51,13 @@ public class MySqlVPN implements VPNDatabase {
rs.getString("method"), rs.getString("isp"), "N/A",
rs.getBoolean("proxy"), rs.getBoolean("cached"), true,
rs.getDouble("latitude"), rs.getDouble("longitude"),
System.currentTimeMillis(), -1);
rs.getTimestamp("inserted").getTime(), -1);
if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) {
VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip));
return Optional.empty();
}
return Optional.of(response);
}
} catch (SQLException throwables) {
@@ -86,7 +78,7 @@ public class MySqlVPN implements VPNDatabase {
*/
@Override
public void cacheResponse(VPNResponse toCache) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
if (isDisabled())
return;
Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`,"
@@ -98,10 +90,18 @@ public class MySqlVPN implements VPNDatabase {
.append(toCache.getLatitude()).append(toCache.getLongitude()).execute();
}
@Override
public void deleteResponse(String ip) {
if(!isDisabled())
return;
Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute();
}
@SneakyThrows
@Override
public boolean isWhitelisted(UUID uuid) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
if (isDisabled())
return false;
ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1")
.append(uuid.toString()).executeQuery();
@@ -112,7 +112,7 @@ public class MySqlVPN implements VPNDatabase {
@SneakyThrows
@Override
public boolean isWhitelisted(String ip) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
if (isDisabled())
return false;
ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1")
.append(ip).executeQuery();
@@ -123,7 +123,7 @@ public class MySqlVPN implements VPNDatabase {
@Override
public void setWhitelisted(UUID uuid, boolean whitelisted) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
if (isDisabled())
return;
if (whitelisted) {
@@ -139,7 +139,7 @@ public class MySqlVPN implements VPNDatabase {
@Override
public void setWhitelisted(String ip, boolean whitelisted) {
if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed())
if (isDisabled())
return;
if(whitelisted) {
@@ -333,6 +333,10 @@ public class MySqlVPN implements VPNDatabase {
System.err.println("MySQL Excepton created" + e.getMessage());
}
}
private boolean isDisabled() {
return !AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed();
}
@Override
public void shutdown() {
@@ -1,11 +1,13 @@
package dev.brighten.antivpn.database.sql.utils;
import com.mysql.cj.jdbc.Driver;
import dev.brighten.antivpn.AntiVPN;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class MySQL {
private static Connection conn;
@@ -13,11 +15,7 @@ public class MySQL {
public static void init() {
try {
if (conn == null || conn.isClosed()) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
Class.forName("com.mysql.jdbc.Driver");
}
DriverManager.registerDriver(new Driver());
conn = DriverManager.getConnection("jdbc:mysql://" + AntiVPN.getInstance().getVpnConfig().getIp()
+ ":" + AntiVPN.getInstance().getVpnConfig().getPort()
+ "/?useSSL=true&autoReconnect=true",
@@ -31,26 +29,23 @@ public class MySQL {
AntiVPN.getInstance().getExecutor().log("Connection to MySQL has been established.");
}
} catch (Exception e) {
AntiVPN.getInstance().getExecutor().log("Failed to load mysql: " + e.getMessage());
e.printStackTrace();
AntiVPN.getInstance().getExecutor().logException("Failed to load mysql: " + e.getMessage(), e);
}
}
public static void initH2() {
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases" + File.separator + "database");
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases");
File databaseFile = new File(dataFolder, "database");
try {
Class.forName("org.h2.Driver");
conn = new NonClosableConnection(DriverManager.getConnection ("jdbc:h2:file:" +
dataFolder.getAbsolutePath(),
AntiVPN.getInstance().getVpnConfig().getUsername(),AntiVPN.getInstance().getVpnConfig().getPassword()));
conn = new NonClosableConnection(new org.h2.jdbc.JdbcConnection("jdbc:h2:file:" +
databaseFile.getAbsolutePath(),
new Properties(), AntiVPN.getInstance().getVpnConfig().getUsername(),
AntiVPN.getInstance().getVpnConfig().getPassword(), false));
conn.setAutoCommit(true);
Query.use(conn);
AntiVPN.getInstance().getExecutor().log("Connection to SQlLite has been established.");
AntiVPN.getInstance().getExecutor().log("Connection to H2 has been established.");
} catch (SQLException ex) {
AntiVPN.getInstance().getExecutor().log("SQLite exception on initialize");
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
AntiVPN.getInstance().getExecutor().log("No H2 library found!");
AntiVPN.getInstance().getExecutor().logException("H2 exception on initialize", ex);
}
}
@@ -58,7 +53,7 @@ public class MySQL {
try {
init();
} catch (Exception e) {
e.printStackTrace();
AntiVPN.getInstance().getExecutor().logException(e);
}
}
@@ -71,7 +66,7 @@ public class MySQL {
conn = null;
}
} catch (Exception e) {
e.printStackTrace();
AntiVPN.getInstance().getExecutor().logException(e);
}
}
@@ -82,7 +77,7 @@ public class MySQL {
try {
return conn.isClosed();
} catch (SQLException e) {
e.printStackTrace();
AntiVPN.getInstance().getExecutor().logException(e);
return true;
}
}
@@ -1,5 +1,7 @@
package dev.brighten.antivpn.message;
import dev.brighten.antivpn.AntiVPN;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@@ -27,6 +29,8 @@ public class MessageHandler {
public void addString(VpnString string, Function<VpnString, String> getter) {
string.setConfigStringGetter(getter);
getter.apply(string);
AntiVPN.getInstance().getExecutor().log("Added string " + string.getKey());
messages.put(string.getKey(), string);
}
@@ -35,5 +39,8 @@ public class MessageHandler {
"&cYou must be a player to execute this command!"), getter);
addString(new VpnString("command-alerts-toggled",
"&7Your player proxy notifications have been set to: &e%state%"), getter);
addString(new VpnString("command-reload-complete",
"&aSuccessfully reloaded KauriVPN plugin!"), getter);
addString(new VpnString("no-permission", "&cNo permission."), getter);
}
}
@@ -19,7 +19,6 @@ public class VpnString {
public VpnString(String key, String defaultMessage) {
this.key = key;
this.defaultMessage = defaultMessage;
this.message = defaultMessage;
}
@SneakyThrows
@@ -30,7 +29,7 @@ public class VpnString {
}
public String getFormattedMessage(Var<String, Object>... replacements) {
String formatted = message;
String formatted = configStringGetter.apply(this);
for (Var<String, Object> replacement : replacements) {
formatted = formatted
@@ -1,6 +1,7 @@
package dev.brighten.antivpn.utils;
import java.io.*;
import java.util.concurrent.ThreadFactory;
import java.util.regex.Pattern;
public class MiscUtils {
@@ -41,6 +42,14 @@ public class MiscUtils {
}
}
public static ThreadFactory createThreadFactory(String threadName) {
return r -> {
Thread thread = new Thread(r);
thread.setName(threadName);
return thread;
};
}
public static boolean isIpv4(String ip)
{
return ipv4.matcher(ip).matches();
@@ -23,17 +23,17 @@ public class YamlConfiguration extends ConfigurationProvider
@Override
protected Yaml initialValue()
{
Representer representer = new Representer()
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
Representer representer = new Representer(options)
{
{
representers.put( Configuration.class, data -> represent( ( (Configuration) data ).self ));
}
};
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
representer.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
return new Yaml( new Constructor(), representer, options );
return new Yaml( new Constructor(new LoaderOptions()), representer, options );
}
};
@@ -0,0 +1,59 @@
package dev.brighten.antivpn.web;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.utils.json.JSONObject;
import dev.brighten.antivpn.utils.json.JsonReader;
import dev.brighten.antivpn.web.objects.QueryResponse;
import dev.brighten.antivpn.web.objects.VPNResponse;
import java.io.IOException;
public class FunkemunkyAPI {
/**
*
* Queries https://funkemunky.cc/vpn API and returns information on the IP
*
* @param ip String
* @param license String
* @param cachedResults boolean
* @return VPNResponse
* @throws JSONException Throws when JSON response is not formatted properly.
* @throws IOException Throws when there is an error connecting to and processing information from API.
*/
public static VPNResponse getVPNResponse(String ip, String license, boolean cachedResults /* faster if set to true*/)
throws JSONException, IOException {
JSONObject result = JsonReader.readJsonFromUrl(String
.format("https://funkemunky.cc/vpn?ip=%s&license=%s&cache=%s",
ip, license.length() == 0 ? "none" : license, cachedResults));
return VPNResponse.fromJson(result);
}
/**
* Feeds into {@link FunkemunkyAPI#getQueryResponse(String)} using "none" as argument
* to grab query information based on the connecting IP address.
*
* @return QueryResponse
* @throws JSONException Throws when JSON response is not formatted properly.
* @throws IOException Throws when there is an error connecting to and processing information from API.
*/
public static QueryResponse getQueryResponse() throws JSONException, IOException {
return getQueryResponse("none");
}
/**
* Queries https://funkemunky.cc/vpn/queryCheck and returns information based on the
* provided licence input.
*
* @param license String
* @return QueryResponse
* @throws JSONException Throws when JSON response is not formatted properly.
* @throws IOException Throws when there is an error connecting to and processing information from API.
*/
public static QueryResponse getQueryResponse(String license) throws JSONException, IOException {
JSONObject result = JsonReader.readJsonFromUrl("https://funkemunky.cc/vpn/queryCheck?license=" + license);
return QueryResponse.fromJson(result);
}
}
@@ -0,0 +1,51 @@
package dev.brighten.antivpn.web.objects;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.utils.json.JSONObject;
import lombok.Builder;
import lombok.Data;
/**
* Used to format the JSON response from https://funkemunky.cc/vpn/queryCheck into an object for project use.
*/
@Data
@Builder(toBuilder = true)
public class QueryResponse {
private boolean validPlan;
private String planType;
private long queries;
private long queriesMax;
/**
* Takes a JSON String and feeds it into {@link QueryResponse#fromJson(JSONObject)}
*
* @param jsonString String (formatted in JSON)
* @return QueryResponse
* @throws JSONException Throws when JSON is not formatted properly.
*/
public static QueryResponse fromJson(String jsonString) throws JSONException {
return fromJson(new JSONObject(jsonString));
}
/**
* Formats response from https://funkemunky.cc/vpn/queryCheck into {@link QueryResponse} for project use.
*
* @param object JSONObject
* @return QueryResponse
* @throws JSONException Throws when JSON is not formatted properly.
*/
public static QueryResponse fromJson(JSONObject object) throws JSONException {
boolean validPlan = object.getBoolean("validPlan");
if(!validPlan) { // Nothing else will be returned from API if validPlan is false.
return QueryResponse.builder().validPlan(false).build();
}
return QueryResponse.builder().validPlan(object.getBoolean("validPlan"))
.planType(object.getString("planType"))
.queries(object.getLong("queries"))
.queriesMax(object.getLong("queryLimit")).build();
}
}
@@ -1,13 +1,13 @@
package dev.brighten.antivpn.utils;
package dev.brighten.antivpn.web.objects;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.utils.json.JSONObject;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@Getter
@Setter
@Data
@AllArgsConstructor
@RequiredArgsConstructor
@Builder
public class VPNResponse {
private String asn, ip, countryName, countryCode, city, timeZone, method, isp, failureReason = "N/A";
@@ -29,34 +29,35 @@ public class VPNResponse {
json.put("proxy", proxy);
json.put("success", success);
json.put("timeZone", timeZone);
json.put("success", true);
json.put("queriesLeft", queriesLeft);
json.put("cached", cached);
return json;
}
/**
* Feeds into {@link VPNResponse#fromJson(JSONObject)} formatting the JSON {@link String} into
* a {@link JSONObject}
*
* @param json String
* @return VPNResponse
*/
public static VPNResponse fromJson(String json) throws JSONException {
JSONObject jsonObject = new JSONObject(json);
if(jsonObject.getBoolean("success")) {
return new VPNResponse(jsonObject.getString("asn"), jsonObject.getString("ip"),
jsonObject.getString("countryName"), jsonObject.getString("countryCode"),
jsonObject.getString("city"), jsonObject.getString("timeZone"),
jsonObject.has("method") ? jsonObject.getString("method") : "N/A",
jsonObject.getString("isp"), "N/A", jsonObject.getBoolean("proxy"),
jsonObject.getBoolean("cached"), jsonObject.getBoolean("success"),
jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"),
jsonObject.getLong("lastAccess"), jsonObject.getInt("queriesLeft"));
} else {
VPNResponse response = new VPNResponse(false);
response.failureReason = jsonObject.getString("failureReason");
return response;
}
return fromJson(new JSONObject(json));
}
public static final VPNResponse FAILED_RESPONSE = VPNResponse.builder()
.success(false)
.failureReason("Internal plugin API error.")
.build();
/**
* Formats response from <a href="https://funkemunky.cc/vpn">...</a> into {@link VPNResponse} for project use.
*
* @param jsonObject JSONObject
* @return VPNResponse
* @throws JSONException Throws when JSON is not formatted properly.
*/
public static VPNResponse fromJson(JSONObject jsonObject) throws JSONException {
if(jsonObject.getBoolean("success")) {
return new VPNResponse(jsonObject.getString("asn"), jsonObject.getString("ip"),
@@ -68,11 +69,8 @@ public class VPNResponse {
jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"),
jsonObject.getLong("lastAccess"), jsonObject.getInt("queriesLeft"));
} else {
VPNResponse response = new VPNResponse(false);
response.failureReason = jsonObject.getString("failureReason");
return response;
return VPNResponse.builder().success(false)
.failureReason(jsonObject.getString("failureReason")).build();
}
}
}
+12 -4
View File
@@ -15,8 +15,8 @@ prefixWhitelists: []
# Configure your database here.
database:
# Enable to cache queries and save alerts state beyond restarts
enabled: false
useCredentials: true
enabled: true
useCredentials: false
#Options Mongo, MySQL, or H2
type: H2
# The database name you would like to use
@@ -50,7 +50,7 @@ alerts:
&7in location &8(&f%city%&7, &f%country%&8)'
# Configuration for country gatekeepings
countries:
# You must use ISO codes for country configuration: https://www.iban.com/country-code
# You must use ISO codes for country configuration: https://www.iban.com/country-codes
# Leave empty to disable this configuration
list: []
# Set whitelist to true to only allow listed country codes, and false to deny listed country codes.
@@ -61,8 +61,16 @@ countries:
commands: []
# The kick message that will be used if commands are configured to use the built-in kicking sytem.
# PlaceHolders: %country% (Country name), %player% (Player name), %code% (Country ISO Code)
vanillaKickReason: "&cSorry, but our server does not allow connections from\n&f%country%"
vanillaKickReason: |-
&cSorry, but our server does not allow connections from
&f%country%
# This will disable any information being sent to https://bstats.org. We recommend you keep this enabled as it helps
# us understand our users and put effort where it is needed. All information sent goes under their privacy as seen
# here: https://bstats.org/privacy-policy
bstats: true
# Here you can configure messages for KauriVPN.
messages:
command-misc-playerRequired: '&cYou must be a player to execute this command!'
command-alerts-toggled: '&7Your player proxy notifications have been set to: &e%state%'
command-reload-complete: '&aSuccessfully reloaded KauriVPN plugin!'
no-permission: '&cNo permission.'
+2
View File
@@ -1,3 +1,5 @@
[![Project Map](https://sourcespy.com/shield.svg)](https://sourcespy.com/github/funkemunkyantivpn/)
# AntiVPN
An antivpn plugin utilizing the KauriVPN API
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Sponge</artifactId>
<repositories>
<repository>
<id>sponge</id>
<url>https://repo.spongepowered.org/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>8.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.9.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
@@ -0,0 +1,31 @@
package dev.brighten.antivpn.sponge;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.sponge.util.StringUtil;
import net.kyori.adventure.text.Component;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
public class SpongePlayer extends APIPlayer {
private final ServerPlayer player;
public SpongePlayer(ServerPlayer player) {
super(player.uniqueId(), player.name(), player.connection().address().getAddress());
this.player = player;
}
@Override
public void sendMessage(String message) {
//player.sendMessage(StringUtil.translateColorCodes('&', message));
}
@Override
public void kickPlayer(String reason) {
player.kick(Component.text(StringUtil.translateColorCodes('&', reason)));
}
@Override
public boolean hasPermission(String permission) {
return player.hasPermission(permission);
}
}
@@ -0,0 +1,31 @@
package dev.brighten.antivpn.sponge;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.PlayerExecutor;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class SpongePlayerExecutor implements PlayerExecutor {
@Override
public Optional<APIPlayer> getPlayer(String name) {
return Optional.empty();
}
@Override
public Optional<APIPlayer> getPlayer(UUID uuid) {
return Optional.empty();
}
@Override
public void unloadPlayer(UUID uuid) {
}
@Override
public List<APIPlayer> getOnlinePlayers() {
return null;
}
}
@@ -0,0 +1,28 @@
package dev.brighten.antivpn.sponge;
import com.google.inject.Inject;
import org.spongepowered.api.Server;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
import org.spongepowered.plugin.builtin.jvm.Plugin;
import java.util.logging.Logger;
@Plugin("kaurivpn")
public class SpongePlugin {
public static SpongePlugin INSTANCE;
//Plugin init
@Inject
private Logger logger;
@Listener
public void onServerStart(final StartedEngineEvent<Server> event) {
INSTANCE = this;
logger.info("Starting AntiVPN services...");
//Start AntiVPN
}
}
@@ -0,0 +1,17 @@
package dev.brighten.antivpn.sponge.util;
public class StringUtil {
public static String translateColorCodes(char altColorChar, String textToTranslate) {
char[] b = textToTranslate.toCharArray();
for(int i = 0; i < b.length - 1; ++i) {
if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) {
b[i] = 167;
b[i + 1] = Character.toLowerCase(b[i + 1]);
}
}
return new String(b);
}
}
+9 -5
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -27,13 +27,13 @@
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>3.0.1</version>
<version>3.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -49,7 +49,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.13.0</version>
<configuration>
<source>8</source>
<target>8</target>
@@ -59,7 +59,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<version>3.5.2</version>
<configuration>
<relocations>
<relocation>
@@ -67,6 +67,10 @@
<!-- Replace this with your package! -->
<shadedPattern>dev.brighten.antivpn.velocity.org.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.brighten.antivpn.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -1,137 +1,184 @@
package dev.brighten.antivpn.velocity;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.scheduler.ScheduledTask;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.velocity.util.StringUtils;
import dev.brighten.antivpn.web.objects.VPNResponse;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class VelocityListener extends VPNExecutor {
private ScheduledTask cacheResetTask;
private final Cache<UUID, VPNResponse> responseCache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(2000)
.build();
@Override
public void registerListeners() {
VelocityPlugin.INSTANCE.getServer().getEventManager()
.register(VelocityPlugin.INSTANCE, this);
VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, DisconnectEvent.class,
event -> AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId()));
VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, LoginEvent.class,
event -> {
if(event.getResult().isAllowed()) {
if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
//Is exempt
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getRemoteAddress()
.getAddress().getHostAddress())
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return;
if (event.getResult().isAllowed()) {
if (event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
//Is exempt
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getRemoteAddress()
.getAddress().getHostAddress())
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return;
checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress(),
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
if(result.isSuccess()) {
// If the countryList() size is zero, no need to check.
// Running country check first
if(AntiVPN.getInstance().getVpnConfig().countryList().size() > 0
// This bit of code will decide whether or not to kick the player
// If it contains the code and it is set to whitelist, it will not kick
// as they are equal and vise versa. However, if the contains does not match
// the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
//Using our built in kicking system if no commands are configured
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().size() == 0) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
// Kicking our player
event.getPlayer().disconnect(LegacyComponentSerializer.builder().character('&')
.build().deserialize(kickReason
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode())));
} else {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = StringUtils
.translateAlternateColorCodes('&',
cmd.replace("%player%",
event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()));
// Running the command from console
VelocityPlugin.INSTANCE.getServer().getCommandManager()
.executeAsync(VelocityPlugin.INSTANCE.getServer()
.getConsoleCommandSource(),
StringUtils.translateAlternateColorCodes('&',
formattedCommand));
}
}
} else if(result.isProxy()) {
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect())
event.getPlayer().disconnect(LegacyComponentSerializer.builder().character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getKickString()));
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
//Ensuring the user wishes to alert to staff
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(AntiVPN.getInstance().getVpnConfig()
.alertMessage()
.replace("%player%",
event.getPlayer().getUsername())
.replace("%reason%",
result.getMethod())
.replace("%country%",
result.getCountryName())
.replace("%city%",
result.getCity())));
if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) {
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
//In case the user wants to run their own commands instead of using the
// built in kicking
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
VelocityPlugin.INSTANCE.getServer().getCommandManager()
.executeAsync(VelocityPlugin.INSTANCE.getServer()
.getConsoleCommandSource(),
StringUtils.translateAlternateColorCodes('&',
command.replace("%player%",
event.getPlayer().getUsername())));
}
}
AntiVPN.getInstance().detections++;
}
} else {
VelocityPlugin.INSTANCE.getLogger()
.log(Level.WARNING,
"The API query was not a success! " +
"You may need to upgrade your license on " +
"https://funkemunky.cc/shop");
if (cached != null && cached.isProxy()) {
event.setResult(ResultedEvent.ComponentResult.denied(Component.text("No")));
return;
}
AntiVPN.getInstance().checked++;
});
}
});
}
}
@Override
public void runCacheReset() {
cacheResetTask = VelocityPlugin.INSTANCE.getServer().getScheduler()
.buildTask(VelocityPlugin.INSTANCE, this::resetCache)
.repeat(20, TimeUnit.MINUTES)
.schedule();
checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress(),
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
if (result.isSuccess()) {
// If the countryList() size is zero, no need to check.
// Running country check first
if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
&& !(AntiVPN.getInstance().getExecutor()
.isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer()
.getRemoteAddress().getAddress().getHostAddress()))
// This bit of code will decide whether or not to kick the player
// If it contains the code and it is set to whitelist, it will not kick
// as they are equal and vise versa. However, if the contains does not match
// the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
//Using our built in kicking system if no commands are configured
if (AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
// Kicking our player
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(kickReason
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))));
VelocityPlugin.INSTANCE.getServer().getScheduler()
.buildTask(VelocityPlugin.INSTANCE, () ->
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(kickReason
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))));
} else {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = StringUtils
.translateAlternateColorCodes('&',
cmd.replace("%player%",
event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()));
// Running the command from console
VelocityPlugin.INSTANCE.getServer().getCommandManager()
.executeAsync(VelocityPlugin.INSTANCE.getServer()
.getConsoleCommandSource(),
StringUtils.translateAlternateColorCodes('&',
formattedCommand));
}
}
} else if (result.isProxy()) {
if (AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
// Delay code execution
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getKickString()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))));
VelocityPlugin.INSTANCE.getServer().getScheduler()
.buildTask(VelocityPlugin.INSTANCE, () ->
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getKickString()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))))
.delay(1, TimeUnit.SECONDS).schedule();
}
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
//Ensuring the user wishes to alert to staff
if (AntiVPN.getInstance().getVpnConfig().alertToStaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(AntiVPN.getInstance().getVpnConfig()
.alertMessage()
.replace("%player%",
event.getPlayer().getUsername())
.replace("%reason%",
result.getMethod())
.replace("%country%",
result.getCountryName())
.replace("%city%",
result.getCity())));
//In case the user wants to run their own commands instead of using the
// built in kicking
if (AntiVPN.getInstance().getVpnConfig().runCommands()) {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
VelocityPlugin.INSTANCE.getServer().getCommandManager()
.executeAsync(VelocityPlugin.INSTANCE.getServer()
.getConsoleCommandSource(),
StringUtils.translateAlternateColorCodes('&',
command.replace("%player%",
event.getPlayer().getUsername())));
}
}
AntiVPN.getInstance().detections++;
}
} else {
VelocityPlugin.INSTANCE.getLogger()
.log(Level.WARNING,
"The API query was not a success! " +
"You may need to upgrade your license on " +
"https://funkemunky.cc/shop");
}
AntiVPN.getInstance().checked++;
});
}
});
}
@Override
public void shutdown() {
if(cacheResetTask != null) {
if (cacheResetTask != null) {
cacheResetTask.cancel();
cacheResetTask = null;
}
@@ -139,8 +186,18 @@ public class VelocityListener extends VPNExecutor {
VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this);
}
@Override
public void log(Level level, String log, Object... objects) {
VelocityPlugin.INSTANCE.getLogger().log(level, String.format(log, objects));
}
@Override
public void log(String log, Object... objects) {
VelocityPlugin.INSTANCE.getLogger().log(Level.INFO, String.format(log, objects));
log(Level.INFO, String.format(log, objects));
}
@Override
public void logException(String message, Exception ex) {
VelocityPlugin.INSTANCE.getLogger().log(Level.SEVERE, message, ex);
}
}
@@ -9,13 +9,14 @@ import java.util.stream.Collectors;
public class VelocityPlayerExecutor implements PlayerExecutor {
private final Map<Player, VelocityPlayer> cachedPlayers = new WeakHashMap<>();
private final Map<UUID, VelocityPlayer> cachedPlayers = new HashMap<>();
@Override
public Optional<APIPlayer> getPlayer(String name) {
Optional<Player> player = VelocityPlugin.INSTANCE.getServer().getPlayer(name);
return player.map(value -> cachedPlayers.computeIfAbsent(value, VelocityPlayer::new));
return player.map(value -> cachedPlayers.computeIfAbsent(value.getUniqueId(),
key -> new VelocityPlayer(value)));
}
@@ -23,13 +24,19 @@ public class VelocityPlayerExecutor implements PlayerExecutor {
public Optional<APIPlayer> getPlayer(UUID uuid) {
Optional<Player> player = VelocityPlugin.INSTANCE.getServer().getPlayer(uuid);
return player.map(value -> cachedPlayers.computeIfAbsent(value, VelocityPlayer::new));
return player.map(value -> cachedPlayers.computeIfAbsent(value.getUniqueId(),
key -> new VelocityPlayer(value)));
}
@Override
public void unloadPlayer(UUID uuid) {
cachedPlayers.remove(uuid);
}
@Override
public List<APIPlayer> getOnlinePlayers() {
return VelocityPlugin.INSTANCE.getServer().getAllPlayers().stream()
.map(pl -> cachedPlayers.computeIfAbsent(pl, VelocityPlayer::new))
.map(pl -> cachedPlayers.computeIfAbsent(pl.getUniqueId(), key -> new VelocityPlayer(pl)))
.collect(Collectors.toList());
}
}
@@ -8,7 +8,6 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.command.Command;
import dev.brighten.antivpn.utils.ConfigDefault;
import dev.brighten.antivpn.velocity.command.VelocityCommand;
import lombok.Getter;
import org.bstats.velocity.Metrics;
@@ -2,6 +2,7 @@ package dev.brighten.antivpn.velocity.command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.command.Command;
import lombok.val;
import net.kyori.adventure.text.Component;
@@ -11,6 +12,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class VelocityCommand implements SimpleCommand {
@@ -26,8 +28,9 @@ public class VelocityCommand implements SimpleCommand {
CommandSource sender = invocation.source();
if(!invocation.source().hasPermission("antivpn.command.*")
&& !invocation.source().hasPermission(command.permission())) {
invocation.source().sendMessage(Component.text("No permission").toBuilder()
.color(TextColor.color(255,0,0)).build());
invocation.source().sendMessage(LegacyComponentSerializer.builder().character('&')
.build().deserialize(AntiVPN.getInstance().getMessageHandler()
.getString("no-permission").getMessage()));
return;
}
@@ -40,6 +43,9 @@ public class VelocityCommand implements SimpleCommand {
.anyMatch(alias -> alias.equalsIgnoreCase(args[0]))) {
if(!sender.hasPermission("antivpn.command.*")
&& !sender.hasPermission(child.permission())) {
invocation.source().sendMessage(LegacyComponentSerializer.builder().character('&')
.build().deserialize(AntiVPN.getInstance().getMessageHandler()
.getString("no-permission").getMessage()));
invocation.source().sendMessage(Component.text("No permission")
.toBuilder().color(TextColor.color(255,0,0)).build());
return;
@@ -73,7 +79,10 @@ public class VelocityCommand implements SimpleCommand {
.mapToObj(i -> args[i + 1]).toArray(String[]::new));
}
}
}else if (children.length > 0){ // && args.length == 0 is always true here
return Arrays.stream(children).map(Command::name).collect(Collectors.toList());
}
return command.tabComplete(new VelocityCommandExecutor(sender), "alias", args);
}
@@ -16,8 +16,9 @@ public class VelocityCommandExecutor implements CommandExecutor {
private final CommandSource sender;
@Override
public void sendMessage(String message) {
sender.sendMessage(LegacyComponentSerializer.builder().character('&').build().deserialize(message));
public void sendMessage(String message, Object... objects) {
sender.sendMessage(LegacyComponentSerializer.builder().character('&').build()
.deserialize(String.format(message, objects)));
}
@Override
+10 -5
View File
@@ -7,7 +7,7 @@
<groupId>dev.brighten.antivpn</groupId>
<artifactId>AntiVPN</artifactId>
<packaging>pom</packaging>
<version>1.7.1.1</version>
<version>1.9.3.1</version>
<modules>
<module>Common</module>
@@ -15,6 +15,7 @@
<module>Bukkit</module>
<module>Assembly</module>
<module>Velocity</module>
<module>Sponge</module>
</modules>
<properties>
@@ -27,7 +28,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.13.0</version>
<configuration>
<source>8</source>
<target>8</target>
@@ -37,7 +38,7 @@
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
@@ -52,6 +53,10 @@
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>funkemunky-releases</id>
<url>https://nexus.funkemunky.cc/content/repositories/releases/</url>
@@ -60,9 +65,9 @@
<dependencies>
<dependency>
<groupId>cc.funkemunky.utils</groupId>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
</dependencies>