Skip to content

Commit

Permalink
cs2 WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
sparkoo committed Nov 12, 2023
1 parent c22301d commit 9a613e4
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 298 deletions.
207 changes: 0 additions & 207 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
package main

import (
"compress/gzip"
"csgo-2d-demo-player/conf"
"csgo-2d-demo-player/pkg/auth"
"csgo-2d-demo-player/pkg/list"
"csgo-2d-demo-player/pkg/log"
"csgo-2d-demo-player/pkg/message"
"csgo-2d-demo-player/pkg/parser"
"csgo-2d-demo-player/pkg/provider/faceit"
"csgo-2d-demo-player/pkg/provider/steam"
"encoding/json"
"fmt"
"io"
"net/http"

"github.com/alexflint/go-arg"
"github.com/gorilla/websocket"
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs"
"go.uber.org/zap"
"google.golang.org/protobuf/proto"
)

var config *conf.Conf
Expand All @@ -34,213 +24,16 @@ func main() {
defer log.Close()

log.L().Debug("using config", zap.Any("config", config))
faceitClient = faceit.NewFaceitClient(config)
steamClient = steam.NewSteamClient(config)
// log.Printf("using config %+v", config)
server()
}

func handleMessages(in chan []byte, out chan []byte) {
for msg := range in {
var messageObj message.Message
err := json.Unmarshal(msg, &messageObj)
if err != nil {
log.Print("failed unmarshal websocket message", err)
}
switch messageObj.MsgType {
case message.Message_PlayRequestType:
go playDemo(out, messageObj.Demo.MatchId)
}
}
}

func server() {
mux := http.NewServeMux()

mux.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets"))))
mux.Handle("/", http.FileServer(http.Dir("web/index/build")))
mux.Handle("/player/", http.StripPrefix("/player", http.FileServer(http.Dir("web/player/build"))))

listService := list.ListService{
Conf: config,
FaceitClient: faceitClient,
}
mux.HandleFunc("/match/list", listService.ListMatches)
mux.HandleFunc("/match/detail", listService.MatchDetails)

// faceit auth
mux.HandleFunc("/auth/faceit/login", faceitClient.LoginHandler)
mux.HandleFunc("/auth/faceit/callback", faceitClient.OAuthCallbackHandler)
mux.HandleFunc("/auth/faceit/logout", faceitClient.LogoutHandler)
mux.Handle("/faceit/api/", http.StripPrefix("/faceit/api/", faceitClient))

// steam auth
mux.HandleFunc("/auth/steam/login", steamClient.LoginHandler)
mux.HandleFunc("/auth/steam/callback", steamClient.OAuthCallbackHandler)
mux.HandleFunc("/auth/steam/logout", steamClient.LogoutHandler)

mux.HandleFunc("/auth/whoami", func(w http.ResponseWriter, r *http.Request) {
if config.Mode == conf.MODE_DEV {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
w.Header().Set("Access-Control-Allow-Credentials", "true")
}

faceitAuth, err := auth.GetAuthCookie(faceit.FaceitAuthCookieName, r, &auth.FaceitAuthInfo{})
if err != nil {
log.L().Info("some error getting the cookie, why???", zap.Error(err))
// http.Error(writer, err.Error(), 500)
}
// log.L().Info("cookie", zap.Any("cok", authCookie))
type whoamiInfo struct {
FaceitNickname string `json:"faceitNickname,omitempty"`
FaceitGuid string `json:"faceitGuid,omitempty"`
SteamId string `json:"steamId,omitempty"`
SteamName string `json:"steamUsername,omitempty"`
SteamAvatar string `json:"steamAvatar,omitempty"`
}
whoami := whoamiInfo{}
if faceitAuth != nil {
whoami.FaceitNickname = faceitAuth.UserInfo.Nickname
whoami.FaceitGuid = faceitAuth.UserInfo.Guid
}

steamAuth, err := auth.GetAuthCookie(steam.SteamAuthCookieName, r, &auth.SteamAuthInfo{})
if err != nil {
log.L().Info("some error getting the cookie, why???", zap.Error(err))
// http.Error(writer, err.Error(), 500)
}
if steamAuth != nil {
whoami.SteamId = steamAuth.UserId
whoami.SteamName = steamAuth.Username
whoami.SteamAvatar = steamAuth.AvatarUrl
}

if whoamiJson, errMarshal := json.Marshal(whoami); errMarshal != nil {
log.L().Error("failed to marshall whoami info", zap.Error(errMarshal))
} else {
_, errWrite := w.Write(whoamiJson)
if errWrite != nil {
log.L().Error("failed to write response", zap.Error(errWrite))
w.WriteHeader(http.StatusServiceUnavailable)
}
}
})

mux.HandleFunc("/ws", func(writer http.ResponseWriter, request *http.Request) {
// Upgrade our raw HTTP connection to a websocket based one
upgrader := websocket.Upgrader{}
if request.Host == "localhost:8080" {
upgrader.CheckOrigin = func(r *http.Request) bool {
return true
}
}
conn, err := upgrader.Upgrade(writer, request, nil)
if err != nil {
log.Print("Error during connection upgradation:", err)
return
}

out := make(chan []byte)
in := make(chan []byte)
go handleMessages(in, out)

// out routine
go func() {
defer func() {
if closeErr := conn.Close(); closeErr != nil {
log.Printf("failed to close connection [out] '%s'", closeErr.Error())
}
}()

for msg := range out {
err = conn.WriteMessage(websocket.BinaryMessage, msg)
if err != nil {
log.Println("Error during message writing:", err)
break
}
}
}()

// in routine
go func() {
defer func() {
if closeErr := conn.Close(); closeErr != nil {
log.Printf("failed to close connection [in] '%s'", closeErr.Error())
}
}()

for {
_, msg, err := conn.ReadMessage()
if err != nil {
closeErr, isCloseErr := err.(*websocket.CloseError)
if !isCloseErr || closeErr.Code != websocket.CloseGoingAway {
log.Println("Error during message reading: ", err)
}
break
}
in <- msg
}
}()
})
log.L().Info("HTTP server listening on ...", zap.String("listen", config.Listen), zap.Int("port", config.Port))
// log.Println("Listening on ", config.Port, " ...")
listenErr := http.ListenAndServe(fmt.Sprintf("%s:%d", config.Listen, config.Port), mux)
log.L().Fatal("failed to listen", zap.Error(listenErr))
}

func playDemo(out chan []byte, matchId string) {
log.L().Info("playing faceit demo", zap.String("matchId", matchId))
if matchId == "" {
sendError("no matchId", out)
return
}
demoFile, closers, err := obtainDemoFile(matchId)
if err != nil {
sendError(err.Error(), out)
return
}
defer func() {
for _, c := range closers {
if closeErr := c.Close(); closeErr != nil {
log.Printf("[%s] failed to close resource. %s", matchId, closeErr)
}
}
}()
err = parser.Parse(demoFile, func(msg *message.Message, tick demoinfocs.GameState) {
sendMessage(msg, out)
})
if err != nil {
sendError(err.Error(), out)
}
}

func sendMessage(msg *message.Message, out chan []byte) {
payload, protoErr := proto.Marshal(msg)
if protoErr != nil {
sendError(protoErr.Error(), out)
}
out <- payload
}

func sendError(errorMessage string, out chan []byte) {
log.Printf("sending error to client: '%s'", errorMessage)
out <- []byte(fmt.Sprintf("{\"msgType\": %d, \"error\": {\"message\": \"%s\"}}", message.Message_ErrorType, errorMessage))
}

func obtainDemoFile(matchId string) (io.Reader, []io.Closer, error) {
closers := make([]io.Closer, 0)

demoFileReader, streamErr := faceitClient.DemoStream(matchId)
if streamErr != nil {
return nil, closers, streamErr
}
closers = append(closers, demoFileReader)

gzipReader, gzipErr := gzip.NewReader(demoFileReader)
if gzipErr != nil {
log.Printf("[%s] Failed to create gzip reader from demo. %s", matchId, gzipErr)
return nil, closers, gzipErr
}
closers = append(closers, gzipReader)
return gzipReader, closers, gzipErr
}
4 changes: 4 additions & 0 deletions web/index/public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ a:hover {
a {
text-decoration-line: none;
}

body {
background-image: url("https://media3.giphy.com/media/toXKzaJP3WIgM/giphy.gif?cid=ecf05e478tqmsss7kgqovsqp0a8qbkfcf72svqjievr53jp2");
}
102 changes: 11 additions & 91 deletions web/index/src/App.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,19 @@
import { useEffect, useState } from 'react';
import './App.css';
import MatchTable from './MatchTable/MatchTable';

function App() {
const [auth, setAuth] = useState([]);
const [serverHost] = useState(window.location.host.includes("localhost") ? "http://localhost:8080" : "")
const [content, setContent] = useState([]);

useEffect(() => {
if (Object.keys(auth).length > 0) {
setContent(<MatchTable auth={auth} serverHost={serverHost} />)
return
}
setContent(<span className="material-icons w3-xxxlarge rotate">autorenew</span>)

fetch(serverHost + "/auth/whoami", { credentials: "include" })
.then(response => response.json())
.then(data => {
if (Object.keys(data).length > 0) {
setAuth(data)
} else {
setContent(<span className="w3-xxxlarge rotate">Connect account first</span>)
}
})
.catch(err => {
console.log(err)
setContent(<span className="w3-xxxlarge rotate">failed to contact server ...</span>)
})
}, [serverHost, auth])

let faceitAuth = (
<div className='faceitAuth'>
<a href={serverHost + "/auth/faceit/login"}>
Connect FACEIT <img src="https://upload.wikimedia.org/wikipedia/commons/5/52/Cib-faceit_%28CoreUI_Icons_v1.0.0%29.svg" height="32" alt="faceit-logo" />
</a>
</div>)
let steamAuth = (
<div className='steamAuth'>
<a href={serverHost + "/auth/steam/login"}>
Connect Steam <img src='https://upload.wikimedia.org/wikipedia/commons/8/83/Steam_icon_logo.svg' height="32" alt="steam-login" />
</a>
</div>
)
if (Object.keys(auth).length > 0) {
if (auth.faceitNickname) {
faceitAuth = (
<div className='faceitAuth'>
<a href={"https://www.faceit.com/en/players/" + auth.faceitNickname} target="_blank" rel="noreferrer">
<img src="/assets/faceit-logo.svg" alt="faceit-logo" height="32" /><span id="faceitNickname">{auth.faceitNickname}</span>
</a>
<a className="material-icons w3-large" href={serverHost + "/auth/faceit/logout"}>logout</a>
return (
<div className="w3-container w3-margin-top">
<div className="w3-row w3-center">
<div className="w3-quarter">
&nbsp;
</div>
)
}
if (auth.steamId) {
steamAuth = (
<div className='steamAuth'>
<a href={"https://steamcommunity.com/profiles/" + auth.steamId} target="_blank" rel="noreferrer">
<img src={auth.steamAvatar} height="32" alt="steam-login" /><span id="steamNickname">{auth.steamUsername}</span>
</a>
<a className="material-icons w3-large" href={serverHost + "/auth/steam/logout"}>logout</a>
<div className="w3-half w3-display-container w3-cell-middle">
<img
src="https://media3.giphy.com/media/4VRgyzM90w0SoT5BV9/giphy.gif?cid=ecf05e47dnwcxzy13u09zyd37843vdgifb9d5bf9d467crti"
className="w3-circle w3-border-blue-gray w3-hover-border-gray w3-padding w3-leftbar w3-rightbar" alt="cs2" style={{width:'100%'}} />
</div>
)
}
}

return (
<div className="App">
<div className="w3-container">
<div className="w3-row">
<div className="w3-col l2">
<br />
</div>
<div className="w3-col l8">
<div className="w3-container w3-xlarge w3-light-grey">
<div className="w3-row">
<div className="w3-col l4 w3-left-align">
<a href="/"><h1>2d.sparko.cz</h1></a>
</div>
<div className='w3-col l4'>
&nbsp;
</div>
<div className="w3-col l4 w3-right-align">
<div className='faceit'>{faceitAuth}</div>
<div className='steam'>{steamAuth}</div>
</div>
</div>
</div>
<div id="searchNote" className="w3-margin w3-container w3-center loader w3-xlarge">
</div>
{content}
</div>
<div className="w3-col l2">
<br />
</div>
<div className="w3-quarter">
&nbsp;
</div>
</div>
</div>
Expand Down

0 comments on commit 9a613e4

Please sign in to comment.