bug fixes, ws rate limit, new graph

main
gabe farrell 3 years ago
parent a3e56fa753
commit 5387401156

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"golang.org/x/time/rate"
) )
// code adapted from the gorilla websocket chat demo code // code adapted from the gorilla websocket chat demo code
@ -49,6 +50,8 @@ type Client struct {
username string username string
auth bool auth bool
limiter rate.Limiter
} }
type Auth struct { type Auth struct {
@ -70,6 +73,7 @@ func (c *Client) readPump() {
c.conn.SetReadLimit(maxMessageSize) c.conn.SetReadLimit(maxMessageSize)
c.conn.SetReadDeadline(time.Now().Add(pongWait)) c.conn.SetReadDeadline(time.Now().Add(pongWait))
c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
c.limiter = *rate.NewLimiter(1, 5)
for { for {
_, message, err := c.conn.ReadMessage() _, message, err := c.conn.ReadMessage()
if err != nil { if err != nil {
@ -78,6 +82,10 @@ func (c *Client) readPump() {
} }
break break
} }
if !c.limiter.Allow() {
c.send <- []byte("{\"type\":\"chaterror\",\"error\":\"You are sending messages too quickly\"}")
continue
}
var v Auth var v Auth
err = json.Unmarshal(message, &v) err = json.Unmarshal(message, &v)
if err == nil { if err == nil {

@ -5,13 +5,15 @@
<div id="until">{{ until }}</div> <div id="until">{{ until }}</div>
</div> </div>
<div id="BetGraph"> <div id="BetGraph">
<div class="pie animate pie-base" :style="tailsStyle"></div> <div class="spin">
<div class="pie animate start-no-round pie-overlap" :style="headsStyle"></div> <div class="tails-pie pie animate pie-base" :style="tailsStyle"></div>
<div class="heads-pie pie animate pie-overlap" :style="headsStyle"></div>
</div>
<div class="data-overlap" id="data"> <div class="data-overlap" id="data">
<div id="headsInfo" class="percent heads">{{ headsPercent }}%</div> <div id="headsInfo" class="percent heads" :class="{ unfocused: User.bet == 'tails' }">{{ headsPercent }}%</div>
<div id="headsPool" class="pool heads"> {{ headsPool }}gp</div> <div id="headsPool" class="pool heads" :class="{ unfocused: User.bet == 'tails' }"> {{ headsPool }}gp</div>
<div id="tailsInfo" class="percent tails">{{ tailsPercent }}%</div> <div id="tailsInfo" class="percent tails" :class="{ unfocused: User.bet == 'heads' }">{{ tailsPercent }}%</div>
<div id="tailsPool" class="pool tails">{{ tailsPool }}gp</div> <div id="tailsPool" class="pool tails" :class="{ unfocused: User.bet == 'heads' }">{{ tailsPool }}gp</div>
</div> </div>
</div> </div>
<div id="lower" v-show="userStore().username != ''"> <div id="lower" v-show="userStore().username != ''">
@ -168,34 +170,22 @@ onMounted(() => {
position:absolute; position:absolute;
border-radius:50%; border-radius:50%;
} }
.pie:before { .heads-pie:before {
inset:0; inset:0;
background: background:
radial-gradient(farthest-side,var(--c) 98%,#0000) top/var(--b) var(--b) no-repeat,
conic-gradient(var(--c) calc(var(--p)*1%),#0000 0); conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
-webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b))); -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b))); mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
} }
.pie:after { .tails-pie:before {
inset:calc(50% - var(--b)/2);
background:var(--c);
transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
.animate {
animation:p 1s .5s both;
}
.start-no-round:before {
inset:0; inset:0;
background: background:
radial-gradient(farthest-side,var(--c) 98%,#0000) top/var(--b) var(--b) no-repeat,
conic-gradient(var(--c) calc(var(--p)*1%),#0000 0); conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
-webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b))); -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b))); mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
} }
.start-no-round:after { .animate {
inset:calc(50% - var(--b)/2); animation:p 1s .5s both;
background:var(--c);
transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
} }
@-moz-keyframes p{ @-moz-keyframes p{
from{--p:0} from{--p:0}
@ -211,7 +201,7 @@ onMounted(() => {
} }
.data-overlap { .data-overlap {
position:relative; position:relative;
bottom:305px; bottom:304px;
left: 50px; left: 50px;
background-color: #001d3d; background-color: #001d3d;
width: 250px; width: 250px;
@ -238,6 +228,12 @@ onMounted(() => {
.tails { .tails {
color:#dc2f91; color:#dc2f91;
} }
.heads.unfocused {
color:#7a661b;
}
.tails.unfocused {
color:#6b214b;
}
.pool.heads { .pool.heads {
padding-bottom: 2em; padding-bottom: 2em;
} }
@ -264,4 +260,15 @@ onMounted(() => {
background-clip: text; background-clip: text;
color: transparent; color: transparent;
} }
.spin {
animation: rotation 20s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
</style> </style>

@ -40,15 +40,45 @@ const ChatColors = {
const _CHAT_MAX_HISTORY = 75; const _CHAT_MAX_HISTORY = 75;
onMounted(() => {
let log = document.getElementById("ChatWindow") function appendLog(item) {
function appendLog(item) { var log = document.getElementById("ChatWindow")
var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1; var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
log.appendChild(item); log.appendChild(item);
if (doScroll) { if (doScroll) {
log.scrollTop = log.scrollHeight - log.clientHeight; log.scrollTop = log.scrollHeight - log.clientHeight;
}
}
function updateChat() {
var log = document.getElementById("ChatWindow")
log.innerHTML = ""
for (let message of Object.values(chatQueue.elements)) {
var item = document.createElement("div")
let fromUser = document.createElement("span")
fromUser.style = `color: ${message.color};`
fromUser.innerText = message.username
item.appendChild(fromUser)
if ('points' in message) {
let chatScore = document.createElement("span")
chatScore.innerText = `(${message.points})`
chatScore.style = `color: ${message.color};font-family: 'Helvetica';font-size: 12px;`
item.appendChild(chatScore)
}
let chatMsg
if (!('msgcolor' in message)) {
//message['msgcolor'] = '#f3f9f8'
} }
chatMsg = document.createElement("span")
chatMsg.style = `color: ${message.msgcolor};`
chatMsg.innerText = `: ${message.message}`
item.appendChild(chatMsg)
appendLog(item)
} }
}
onMounted(() => {
WS.addEventListener("message", function (evt) { WS.addEventListener("message", function (evt) {
let MSGs = evt.data.split('\n') let MSGs = evt.data.split('\n')
MSGs.forEach((i) => { MSGs.forEach((i) => {
@ -58,27 +88,22 @@ onMounted(() => {
if (chatQueue.length >= _CHAT_MAX_HISTORY) { if (chatQueue.length >= _CHAT_MAX_HISTORY) {
chatQueue.dequeue() chatQueue.dequeue()
} }
log.innerHTML = "" updateChat()
for (let message of Object.values(chatQueue.elements)) { } else if (wsMsg.type == 'chaterror') {
var item = document.createElement("div") chatQueue.enqueue({
let fromUser = document.createElement("span") username: 'Not Sent',
fromUser.style = `color: ${message.color};` color: '#555',
fromUser.innerText = message.username message: wsMsg.error,
item.appendChild(fromUser) msgcolor: '#555'
let chatScore = document.createElement("span") })
chatScore.innerText = `(${message.points})` updateChat()
chatScore.style = `color: ${message.color};font-family: 'Helvetica';font-size: 12px;`
item.appendChild(chatScore)
let chatMsg = document.createTextNode(`: ${message.message}`)
item.appendChild(chatMsg)
appendLog(item)
}
} }
}) })
}) })
}) })
function sendChat() { function sendChat() {
if (chat.value == '') { return }
if (chat.value.startsWith("/color")) { if (chat.value.startsWith("/color")) {
let newColor = chat.value.split(" ")[1] let newColor = chat.value.split(" ")[1]
if (newColor in ChatColors) { if (newColor in ChatColors) {

@ -6,7 +6,7 @@ module.exports = defineConfig({
module.exports = { module.exports = {
devServer: { devServer: {
host: "localhost", host: "localhost",
port: 8000, port: 8080,
proxy: { proxy: {
"/": { "/": {
target: "http://localhost:8000", target: "http://localhost:8000",

@ -12,7 +12,7 @@ import (
/* /*
0.0.4 0.0.4
- added rate limiting - added rate limiting for http and ws
- added captcha for account creation - added captcha for account creation
- added WebSocket authentication - added WebSocket authentication
- fixed BetInput bugs (NaN, decimals) - fixed BetInput bugs (NaN, decimals)

Loading…
Cancel
Save