first commit
This commit is contained in:
commit
b9df9f5a4c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
# Discord-Linux Multi User Chatroom
|
||||||
|
The Discord-Linux Multi User Chatroom is designed to work along side the Discord-Linux API.
|
||||||
|
|
||||||
|
This client serves as a multi user chatroom using websockets. As well as allowing users to interact with their containers right within the room.
|
||||||
|
|
||||||
|
When a new user joins, they will be asked for their token, simply use /api-key to generate a token.
|
33
index.js
Normal file
33
index.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { createServer } from 'http';
|
||||||
|
import staticHandler from 'serve-handler';
|
||||||
|
import ws, { WebSocketServer } from 'ws';
|
||||||
|
let count = 0
|
||||||
|
//serve static folder
|
||||||
|
const server=createServer((req,res)=>{ // (1)
|
||||||
|
return staticHandler(req,res,{public: 'public'})
|
||||||
|
});
|
||||||
|
|
||||||
|
const wss=new WebSocketServer({server}) // (2)
|
||||||
|
wss.on('connection',(client)=>{
|
||||||
|
console.log('A new Client connected !')
|
||||||
|
count++
|
||||||
|
let clientID = "User" + count
|
||||||
|
broadcast("[SVR] A user has started a session! Session #" + count + " during our runtime! Say Hello!")
|
||||||
|
|
||||||
|
client.on('message',(msg)=>{ // (3)
|
||||||
|
console.log(`Message:${msg}`);
|
||||||
|
broadcast(msg)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function broadcast(msg) { // (4)
|
||||||
|
for(const client of wss.clients){
|
||||||
|
if(client.readyState === ws.OPEN){
|
||||||
|
client.send(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.listen(process.argv[2] || 8083,()=>{
|
||||||
|
console.log(`server listening...`);
|
||||||
|
})
|
1168
package-lock.json
generated
Normal file
1168
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
package.json
Normal file
22
package.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "chat-app",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node index.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^13.8.1",
|
||||||
|
"font-selector": "^1.1.8",
|
||||||
|
"node-fetch": "^3.2.8",
|
||||||
|
"nodemon": "^2.0.15",
|
||||||
|
"serve-handler": "^6.1.3",
|
||||||
|
"ws": "^8.5.0"
|
||||||
|
}
|
||||||
|
}
|
10
pm2start.json
Normal file
10
pm2start.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"apps": [
|
||||||
|
{
|
||||||
|
"name": "ROOO",
|
||||||
|
"script": "./process.sh",
|
||||||
|
"args" : ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
2
process.sh
Normal file
2
process.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
node index.js
|
182
public/index.css
Normal file
182
public/index.css
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
html{
|
||||||
|
font-size: 55.5%;
|
||||||
|
|
||||||
|
height: auto !important;
|
||||||
|
padding-bottom: 300px !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
background-color: black !important;
|
||||||
|
margin:0;
|
||||||
|
padding: 0;
|
||||||
|
display:flex;
|
||||||
|
justify-content:center;
|
||||||
|
color: grey;
|
||||||
|
overflow: scroll;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
/* Internet Explorer 10+ */
|
||||||
|
scrollbar-width: none;
|
||||||
|
/* Firefox */
|
||||||
|
font-family: 'Coda', cursive;
|
||||||
|
font-size: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
/* for Internet Explorer, Edge */
|
||||||
|
scrollbar-width: none;
|
||||||
|
/* for Firefox */
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
body::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
/* for Chrome, Safari, and Opera */
|
||||||
|
}
|
||||||
|
.container{
|
||||||
|
margin-top: 5rem;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
width: 70%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
.msg{
|
||||||
|
color:gray !important;
|
||||||
|
font-size: 2rem;
|
||||||
|
white-space: pre;
|
||||||
|
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
.msgCtn{
|
||||||
|
margin: 1rem 0;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
background-color: rgb(34, 33, 33);
|
||||||
|
white-space:pre-wrap;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 2rem;
|
||||||
|
color: gray !important;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
}
|
||||||
|
.msgForm{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
.input{
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
height: 40px;
|
||||||
|
flex: 4;
|
||||||
|
margin-right: 2rem;
|
||||||
|
border:none;
|
||||||
|
border-radius: .5rem;
|
||||||
|
padding: 2px 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: gray;
|
||||||
|
background-color:rgb(19, 18, 18);
|
||||||
|
font-family: 'Coda', cursive;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
.input:focus{
|
||||||
|
background-color:black
|
||||||
|
|
||||||
|
}
|
||||||
|
.btn{
|
||||||
|
|
||||||
|
height:5rem;
|
||||||
|
flex: 1;
|
||||||
|
display:flex;
|
||||||
|
justify-content:center;
|
||||||
|
align-items:center;
|
||||||
|
border-radius: .5rem;
|
||||||
|
color: grey !important;
|
||||||
|
border:1px solid grey !important;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-family: 'Coda', cursive;
|
||||||
|
background-color:black !important;
|
||||||
|
}
|
||||||
|
.btn2{
|
||||||
|
|
||||||
|
height:5rem;
|
||||||
|
display:flex;
|
||||||
|
justify-content:center;
|
||||||
|
align-items:center;
|
||||||
|
border-radius: .5rem;
|
||||||
|
color: grey !important;
|
||||||
|
border:1px solid grey !important;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-family: 'Coda', cursive;
|
||||||
|
background-color:black !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hr {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 10px;
|
||||||
|
left: -0.5vw;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
font-family: 'Coda', cursive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 0 through 99 {
|
||||||
|
hr:nth-child(#{$i}) {
|
||||||
|
@if $i%5==1 {
|
||||||
|
@if $i%10==1 {
|
||||||
|
width: 25px;
|
||||||
|
} @else {
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transform: translateX(#{100 * ($i - 1)/98}vw) rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr:nth-child(100) {
|
||||||
|
width: 120%;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.itsme {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 1;
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #fffc;
|
||||||
|
text-decoration: underline;
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
background-color: hsl(31deg, 43%, 22%);
|
||||||
|
padding: 10px 10px 10px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
left: calc(50% - 139px);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
footer {
|
||||||
|
position: fixed;
|
||||||
|
height: 5%;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
header {
|
||||||
|
position: fixed;
|
||||||
|
height: 5%;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
display:inline-block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
248
public/index.html
Normal file
248
public/index.html
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Coda&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||||
|
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/atom-one-dark.min.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/go.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
|
||||||
|
<title>Discord-Linux Multi User Session</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header class="fixed-bottom text-center text-white bg-transparent col-auto">
|
||||||
|
<!-- Grid container -->
|
||||||
|
<h1>Discord-Linux Multi User Terminal (Using the Discord-Linux API)</h1>
|
||||||
|
<CENTER>
|
||||||
|
<h3>Type "exit" to logout and "clear" to clean old messages</h3>
|
||||||
|
</CENTER>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<!-- Grid container -->
|
||||||
|
|
||||||
|
<!-- Copyright -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<body onload="settoken()">
|
||||||
|
<div class="container">
|
||||||
|
<div id="messages" class='code' class="messages"></div>
|
||||||
|
|
||||||
|
<footer class="fixed-bottom text-center text-white bg-transparent">
|
||||||
|
<!-- Grid container -->
|
||||||
|
<form id="msgForm" class="msgForm">
|
||||||
|
<input bg-transparent type="text" height="200px" placeholder="Send message" class="input"
|
||||||
|
id="inputBox" />
|
||||||
|
<input type="submit" class="btn" value="Send" class="bg-transparent">
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Grid container -->
|
||||||
|
|
||||||
|
<!-- Copyright -->
|
||||||
|
</footer>
|
||||||
|
<!--
|
||||||
|
<button class="top-right btn2 btn-primary pull-right" onclick="removeTerminalContent()" >Clear</button>
|
||||||
|
<button class="btn2 btn-primary pull-right" onclick="logout();">Logout</button>
|
||||||
|
-->
|
||||||
|
<!-- <button class="btn" style="height:200px;width:200px" onclick="removeTerminalContent()">Clear</button> -->
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
let prefix = ">"
|
||||||
|
let userid
|
||||||
|
|
||||||
|
function setCookie(cname, cvalue, exdays) {
|
||||||
|
const d = new Date();
|
||||||
|
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
||||||
|
let expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTerminalContent() {
|
||||||
|
let terminal = document.getElementById("messages")
|
||||||
|
terminal.innerHTML = ""
|
||||||
|
let ctn = document.getElementById("msgCtn")
|
||||||
|
ctn.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie(cname) {
|
||||||
|
let name = cname + "=";
|
||||||
|
let ca = document.cookie.split(';');
|
||||||
|
for (let i = 0; i < ca.length; i++) {
|
||||||
|
let c = ca[i];
|
||||||
|
while (c.charAt(0) == ' ') {
|
||||||
|
c = c.substring(1);
|
||||||
|
}
|
||||||
|
if (c.indexOf(name) == 0) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function settoken() {
|
||||||
|
if (!getCookie("token")) {
|
||||||
|
let userToken = prompt("A token for the Discord-Linux API is required to login.\nPlease enter your token below:", "");
|
||||||
|
if (userToken == "null" || userToken == null || userToken == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userToken != null) {
|
||||||
|
setCookie("token", userToken, 1);
|
||||||
|
fetch('https://api.discord-linux.com/hello?token=' + getCookie("token")).then(response => response.json()).then(data => {
|
||||||
|
console.log(data.message.replace("Hello, ", "").replace(">", ""))
|
||||||
|
if (!data.message.replace("Hello, ", "").replace("!", "")) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
setCookie("userid", data.message.replace("Hello, ", "").replace("!", ""), 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
setCookie("token", "", -1)
|
||||||
|
setCookie("userid", "", -1)
|
||||||
|
setCookie("pwd", "", -1)
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ws = new WebSocket(`wss://${window.document.location.host}`);
|
||||||
|
ws.binaryType = "blob";
|
||||||
|
// Log socket opening and closing
|
||||||
|
ws.addEventListener("open", event => {
|
||||||
|
console.log("Websocket connection opened");
|
||||||
|
});
|
||||||
|
ws.addEventListener("close", event => {
|
||||||
|
console.log("Websocket connection closed");
|
||||||
|
});
|
||||||
|
ws.onmessage = function (message) {
|
||||||
|
console.log(ws)
|
||||||
|
const msgDiv = document.createElement('div');
|
||||||
|
msgDiv.classList.add('msgCtn');
|
||||||
|
if (message.data instanceof Blob) {
|
||||||
|
reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
msgDiv.innerHTML = reader.result;
|
||||||
|
document.getElementById('messages').appendChild(msgDiv);
|
||||||
|
};
|
||||||
|
reader.readAsText(message.data);
|
||||||
|
} else {
|
||||||
|
console.log("Result2: " + message.data);
|
||||||
|
if (getCookie("userid")) {
|
||||||
|
msgDiv.innerHTML = message.data;
|
||||||
|
document.getElementById('messages').appendChild(msgDiv);
|
||||||
|
} else {
|
||||||
|
setCookie("userid", userid, 1);
|
||||||
|
setCookie("pwd", "/", 1);
|
||||||
|
msgDiv.innerHTML = message.data;
|
||||||
|
document.getElementById('messages').appendChild(msgDiv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const form = document.getElementById('msgForm');
|
||||||
|
form.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const message = document.getElementById('inputBox').value;
|
||||||
|
let x = getCookie("userid");
|
||||||
|
let pwd = document.pwd;
|
||||||
|
if (message.startsWith(">cd" || message.startsWith("> cd"))) {
|
||||||
|
let newPwd = message.replace(">cd ", "").replace("> cd", "");
|
||||||
|
if (newPwd.startsWith("/")) {
|
||||||
|
pwd = newPwd;
|
||||||
|
} else {
|
||||||
|
pwd = pwd + "/" + newPwd;
|
||||||
|
}
|
||||||
|
setCookie("pwd", newPwd, 1);
|
||||||
|
ws.send("[SRV] " + x + ": I have set your directory to: " + newPwd);
|
||||||
|
} else
|
||||||
|
// ws.send(x + ": " + message);
|
||||||
|
if (message.startsWith(">")) {
|
||||||
|
if (x == "undefined" || x == "") {
|
||||||
|
return settoken()
|
||||||
|
}
|
||||||
|
ws.send(x + ": " + message);
|
||||||
|
(async () => {
|
||||||
|
let commandToSend = message.replace(">", "").replace("> ", "")
|
||||||
|
const rawResponse = await fetch('https://api.discord-linux.com/exec', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-discord-linux-auth': getCookie("token")
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"cmd": commandToSend,
|
||||||
|
"pwd": getCookie("pwd")
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const content = await rawResponse.json();
|
||||||
|
console.log(content);
|
||||||
|
console.log(content.stdout)
|
||||||
|
|
||||||
|
if (x == "undefined" || x == "") {
|
||||||
|
return settoken()
|
||||||
|
}
|
||||||
|
if (content.stdout == "") {
|
||||||
|
|
||||||
|
if (x == "undefined" || x == "") {
|
||||||
|
return settoken()
|
||||||
|
}
|
||||||
|
return ws.send(`Response for ${x + ":" + " Command: " + commandToSend + "\n"}Done.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ws.send(`Response for ${x + ":" + " Command: " + commandToSend + "\n"}${content.stdout}`);
|
||||||
|
})();
|
||||||
|
} else {
|
||||||
|
if (message == "clear") {
|
||||||
|
return removeTerminalContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == "exit") {
|
||||||
|
return logout()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x == "undefined" || x == "") {
|
||||||
|
return settoken()
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.send(`${x}: ${message}`);
|
||||||
|
}
|
||||||
|
document.getElementById('inputBox').value = ''
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
31
public/logout.html
Normal file
31
public/logout.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Courgette&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/atom-one-dark.min.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/go.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
|
||||||
|
<title>Discord-Linux Multi User Session</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<CENTER><h1><BR><BR><h1>Discord-Linux Multi Chat</h1><BR><BR><BR>
|
||||||
|
|
||||||
|
<h2>You have been logged out. <a href="https://chat.discord-linux.com">Click Here</a> to log back in.</h2>
|
||||||
|
<BR><BR><img src="https://discord-linux.com/images/tux.gif" alt="Tux">
|
||||||
|
</CENTER>
|
||||||
|
</h1>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user