Merge pull request #25 from victormylle/Discord_Verify

Discord verify
This commit is contained in:
victormylle
2020-11-06 23:29:59 +01:00
committed by GitHub
16 changed files with 482 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.idea/
__pycache__
DiscordVerifier/out
local.db

BIN
DiscordVerifier/.DS_Store vendored Executable file

Binary file not shown.

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="spigot-1.15.2" level="project" />
</component>
</module>

118
DiscordVerifier/src/Main.java Executable file
View File

@@ -0,0 +1,118 @@
// 25216 --> uuid server
// 25224 --> send chat server
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
public class Main extends JavaPlugin {
Thread serversocket;
Thread uuidServerThread;
ServerSocket uuidServerSocket;
ServerSocket chatServerSocket;
public void onEnable() {
getLogger().info("DiscordVerifier Plugin enabled");
PluginManager pm = getServer().getPluginManager();
start_socketserver();
start_uuid_server();
}
public void start_uuid_server(){
uuidServerThread = new Thread(() -> {
try{
uuidServerSocket = new ServerSocket(25216);
while (true) {
Socket s = uuidServerSocket.accept();
PrintWriter out =
new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String inputLine;
inputLine = in.readLine();
if (inputLine != null) {
System.out.println("minecraftname: " + inputLine);
Player player = getServer().getPlayer(inputLine);
if (player == null){
out.println("PlayerError");
}else {
System.out.println(player.getUniqueId().toString());
UUID uuid = player.getUniqueId();
out.println(uuid.toString());
}
}
}
} catch (Exception e) {
System.out.println(e);
}
});
uuidServerThread.start();
}
public void start_socketserver() {
serversocket = new Thread(() -> {
try{
chatServerSocket = new ServerSocket(25224);
while (true) {
Socket s = chatServerSocket.accept();
PrintWriter out =
new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String inputLine;
inputLine = in.readLine();
if (inputLine != null) {
System.out.println("message: " + inputLine);
String[] info = inputLine.split("\t");
String discordname = info[0];
Player player = getServer().getPlayer(info[1]);
if (player == null){
out.println("PlayerError");
}else {
out.println("success");
String code = info[2];
send_chat(discordname, player, code);
}
}
}
} catch (Exception e) {
System.out.println(e);
}
});
serversocket.start();
}
public void send_chat(String discordname, Player player, String code){
player.sendMessage(discordname + " wants to link your account\nEnter this code in discord: " + code);
}
public void onDisable() {
try {
chatServerSocket.close();
uuidServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
uuidServerThread.stop();
serversocket.stop();
getLogger().info("Plugin disabled");
}
}

5
DiscordVerifier/src/plugin.yml Executable file
View File

@@ -0,0 +1,5 @@
name: DiscordVerifier
main: Main
version: 0.0.1
description: Verify Mincraftnames
api-version: 1.13

0
README.md Normal file → Executable file
View File

0
bot.py Normal file → Executable file
View File

0
cogs/modcommands.py Normal file → Executable file
View File

181
cogs/playerlink.py Executable file
View File

@@ -0,0 +1,181 @@
import discord
from discord.ext import commands
import random
import string
import socket
import asyncio
import threading
from data import constants
from data.DatabaseConnection import *
# 25216 --> uuid server
# 25224 --> send chat server
def get_random_string(length):
# Random string with the combination of lower and upper case
letters = string.ascii_letters + "0123456789"
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str
class PlayerError(Exception):
pass
class WrongCodeError(Exception):
pass
def get_player_uuid(minecraftname):
HOST = '192.168.1.214' # The server's hostname or IP address
PORT = 25216 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.send(bytes("{}\n".format(minecraftname), encoding="ascii"))
data = s.recv(1024)
data_string = data.decode("utf-8").strip('\n')
if data_string == "PlayerError":
raise PlayerError()
return data_string
def send_chat(discordname, minecraftname, code):
HOST = '192.168.1.214' # The server's hostname or IP address
PORT = 25224 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.send(bytes("{}\t{}\t{}\n".format(discordname, minecraftname, code), encoding="ascii"))
data = s.recv(1024)
data_string = data.decode("utf-8").strip('\n')
if data_string == "PlayerError":
raise PlayerError()
return data_string
class PlayerLink(commands.Cog):
def __init__(self, client):
self.client = client
def get_linked_role(self):
return discord.utils.get(self.client.get_guild(constants.WorldCraft).roles, id=constants.roleLinked)
@commands.command(name="Link")
async def link(self, ctx, arg):
channelid = ctx.channel.id
authorid = ctx.author.id
code = get_random_string(8)
def check(message: discord.Message):
return message.channel.id == channelid and message.author.id == authorid
# creates the embed for the link message
def create_embed(discord_author, minecraftname, timer, error=None, success=False):
embed = discord.Embed(title="WorldCraft Linker")
embed.add_field(name="How to:", value= "A code has been sent to your minecraft chat in the WorldCraft server.\nSend the code in this channel.")
embed.add_field(name="Minecraft Name:", value=f"{minecraftname}", inline=False)
embed.add_field(name="Discord Name:", value=f"{discord_author.mention}", inline=False)
# use dictionary and set color string before the message: example => r(ed):message
if isinstance(error, WrongCodeError):
embed.add_field(name="Error", value=f"The code is wrong!", inline=False)
embed.colour = discord.Colour.red()
elif (success == True):
embed.add_field(name="Success", value=f"The link was successfull!", inline=False)
embed.colour = discord.Colour.green()
elif (timer.ended):
embed.add_field(name="Timer", value=f"The code is expired!", inline=False)
embed.colour = discord.Colour.red()
elif (timer.minutes == 2):
embed.add_field(name="Timer", value=f"The code will expire in { str(timer.minutes)} minutes", inline=False)
embed.colour = discord.Colour.orange()
elif (timer.minutes < 2):
embed.add_field(name="Timer", value=f"The code will expire in less than { str(timer.minutes + 1)} {'minutes' if timer.minutes + 1 > 1 else 'minute'}", inline=False)
embed.colour = discord.Colour.orange()
else:
embed.add_field(name="Timer", value=f"The code will expire in {str(timer.minutes).zfill(2)}:{str(timer.seconds).zfill(2)}", inline=False)
embed.colour = discord.Colour.orange()
return embed
async def update_timer(timer, message):
while (not timer.ended):
await asyncio.sleep(1)
timer.update()
# maybe create a task from this because this takes some time -> timer not accurate
if ((timer.minutes < 2 and timer.seconds == 59) or (timer.minutes == 0 and timer.seconds == 0)):
asyncio.create_task(message.edit(embed=create_embed(ctx.author, arg, timer)))
try:
uuid = get_player_uuid(arg)
send_chat(ctx.author.name, arg, code)
#message_send_time =
timer = Timer()
message = await ctx.send(embed=create_embed(ctx.author, arg, timer))
# Start timer in background
task = asyncio.create_task(update_timer(timer, message))
# Wait for the code response
msg = await self.client.wait_for('message', check=check)
if msg.content == code:
dbLinker = PlayerDBLinker()
try:
dbLinker.linkPlayer(uuid, authorid)
await ctx.author.add_roles(self.get_linked_role())
timer.ended = True
await message.edit(embed=create_embed(ctx.author, arg, timer, success=True))
except SQLInsertError:
await message.edit(embed=create_embed(ctx.author, arg, timer))
finally:
dbLinker.closeconnections()
else:
# this stops the timer task
task.cancel()
timer.ended = True
await message.edit(embed=create_embed(ctx.author, arg, timer, WrongCodeError()))
except PlayerError:
await ctx.send("Player '" + arg + "' not found")
#except:
# await ctx.send("Something went wrong")
@commands.command(name="Unlink")
async def unlink(self, ctx, arg):
authorid = ctx.author.id
dbLinker = PlayerDBLinker()
try:
dbLinker.unlinkPlayer(arg, authorid)
await ctx.author.remove_roles(self.get_linked_role())
await ctx.send("Unlinked your account")
except UnLinkError:
await ctx.send("The unlink was unsuccessfull")
except WrongMinecraftName:
await ctx.send("Wrong minecraft name!")
except PlayerNotLinked:
await ctx.send("Player not linked!")
finally:
dbLinker.closeconnections()
class Timer():
def __init__(self):
self.minutes = 2
self.seconds = 0
self.ended = False
def update(self):
if (self.minutes > 0 and self.seconds == 0):
self.minutes -= 1
self.seconds = 59
elif (self.seconds > 0):
self.seconds -= 1
if (self.minutes == 0 and self.seconds == 0):
self.ended = True
def setup(client):
client.add_cog(PlayerLink(client))

46
cogs/servertatus.py Executable file
View File

@@ -0,0 +1,46 @@
import discord
from discord.ext import commands
from mcstatus import MinecraftServer
class ServerStatus(commands.Cog):
def __init__(self, client):
self.client = client
@commands.command(name="Ping", aliases=["Status"])
async def ping(self, ctx):
servers = {"Earth": "25568", "Moon": "25567"}
ip = "81.82.224.207:"
# List of colours for the amount of servers that are online
upColours = [discord.Colour.red(), discord.Colour.orange(), discord.Colour.green()]
embed = discord.Embed()
embed.set_author(name="Status")
# Amount of servers that are online
upCounter = 2
# Add field for all the servers (for-loop so nothing has to be changed for future servers)
for server in servers:
minecraftServer = MinecraftServer.lookup(ip + servers[server])
try:
# Online
latency = f":green_circle: Server replied in {minecraftServer.ping()}ms."
except ConnectionRefusedError:
# Offline
upCounter -= 1
latency = ":red_circle: Server is offline."
embed.add_field(name=server, value=latency, inline=False)
# Set the embed colour
embed.colour = upColours[upCounter]
# Bot's latency
embed.add_field(name="WorldCraft Bot", value=f":green_circle: {round(self.client.latency * 1000)}ms")
await ctx.send(embed=embed)
def setup(client):
client.add_cog(ServerStatus(client))

100
data/DatabaseConnection.py Executable file
View File

@@ -0,0 +1,100 @@
import mysql.connector
class WrongMinecraftName(Exception):
pass
class SQLInsertError(Exception):
pass
class UnLinkError(Exception):
pass
class PlayerNotLinked(Exception):
pass
class DatabaseConnection:
# databases -> worldcraft and worldcraft_discord
def __init__(self, database="worldcraft_discord"):
if database == "worldcraft_discord":
self.mydb = mysql.connector.connect(
host="192.168.1.251",
user="worldcraft_discord",
password="aquev5vcwhLwTdRt",
database=database
)
elif database == "s13_worldcraft":
self.mydb = mysql.connector.connect(
host="192.168.1.251",
user="u13_f2zpWZpIKY",
password="@fZQ6Uu3+U^WH1i2JNemgTC7",
database=database
)
self.cursor = self.mydb.cursor()
def get_db(self):
return self.mydb
def get_cursor(self):
return self.cursor
def close(self):
self.mydb.close()
# this will save the uuid of the player and discord id
class PlayerDBLinker:
def __init__(self):
self.tablename = "playerlinks"
self.discorddbconn = DatabaseConnection(database="worldcraft_discord")
self.serverdbconn = DatabaseConnection(database="s13_worldcraft")
# check if table exists
cursor = self.discorddbconn.get_cursor()
cursor.execute("create table IF NOT EXISTS {} (id int NOT NULL PRIMARY KEY AUTO_INCREMENT, minecraftUUID varchar(36) NOT NULL, discordid TINYTEXT NOT NULL)".format(self.tablename))
def checkPlayerLink(self, minecraftUUID, discordid):
cursor = self.discorddbconn.get_cursor()
cursor.execute("select count(*) from {} where minecraftUUID='{}' AND discordid='{}'".format(self.tablename, minecraftUUID, discordid))
res = cursor.fetchone()
return res[0] == 1
def minecraftUUIDused(self, minecraftUUID):
cursor = self.discorddbconn.get_cursor()
cursor.execute("select count(*) from {} where minecraftUUID='{}'".format(self.tablename, minecraftUUID))
res = cursor.fetchone()
return res[0] >= 1
def discordidused(self, discordid):
cursor = self.discorddbconn.get_cursor()
cursor.execute("select count(*) from {} where discordid='{}'".format(self.tablename, discordid))
res = cursor.fetchone()
return res[0] >= 1
def linkPlayer(self, minecraftUUID, discordid):
cursor = self.discorddbconn.get_cursor()
sql = "insert into {} (minecraftUUID, discordid) VALUES (%s, %s)".format(self.tablename)
val = (minecraftUUID, discordid)
try:
cursor.execute(sql, val)
self.discorddbconn.get_db().commit()
except:
raise SQLInsertError()
def unlinkPlayer(self, minecraftname, discordid):
# get uuid from server database -> check if in linkerdatabase
serverdb_cursor = self.serverdbconn.get_cursor()
discorddb_cursor = self.discorddbconn.get_cursor()
sql = "SELECT playerUUID FROM playerprofiles WHERE playerName = '{}' LIMIT 1".format(minecraftname)
serverdb_cursor.execute(sql)
res = serverdb_cursor.fetchone()
if res == None:
raise WrongMinecraftName()
playeruuid = res[0]
if self.checkPlayerLink(playeruuid, discordid):
sql2 = f"DELETE FROM {self.tablename} WHERE minecraftUUID = '{playeruuid}' AND discordid = '{discordid}'"
discorddb_cursor.execute(sql2)
res2 = self.discorddbconn.get_db().commit()
else:
raise PlayerNotLinked()
def closeconnections(self):
self.discorddbconn.close()
self.serverdbconn.close()

6
data/constants.py Normal file → Executable file
View File

@@ -9,6 +9,12 @@ roleAdmin = 730709756125249588
roleMod = 688328855605346339
roleOwner = 687996070986383436
# User roles
roleLinked = 730709907275382904 # given when minecraft account is connected with discord account
# Guild id
WorldCraft = 683422015394545665
adminRoles = [roleAdmin, roleOwner]
modPlusRoles = [roleAdmin, roleMod, roleOwner]

0
files/images/server_icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

0
functions/checks.py Normal file → Executable file
View File

View File

@@ -1,2 +1,3 @@
discord.py==1.5.0
mcstatus==4.0.0
mysql-connector-python==8.0.21

12
sockettest.py Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env python3
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 3333 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Pieter suckt\n')
data = s.recv(1024)
print('Received', repr(data))