diff options
author | dgy <dgy@texto-plano.xyz> | 2021-02-02 12:03:03 -0300 |
---|---|---|
committer | dgy <dgy@texto-plano.xyz> | 2021-02-02 12:03:03 -0300 |
commit | fadb734aa0cdfce93a9ebc4aa8bfb632cdea89ed (patch) | |
tree | 8c164b3b8238d2fa0dad4f3c571371b570c4c1f1 | |
parent | 72c411f5d3de16f0c574ff6045114455142f7964 (diff) | |
download | sshtron-fadb734aa0cdfce93a9ebc4aa8bfb632cdea89ed.tar.gz |
-rw-r--r-- | README.txt (renamed from README.md) | 49 | ||||
-rw-r--r-- | game.go | 21 | ||||
-rw-r--r-- | main.go | 21 | ||||
-rw-r--r-- | static/index.html | 35 |
4 files changed, 56 insertions, 70 deletions
@@ -1,16 +1,16 @@ -# ![SSHTron](https://cdn.rawgit.com/zachlatta/sshtron/master/logo.svg) - SSHTron is a multiplayer lightcycle game that runs through SSH. Just run the command below and you'll be playing in seconds: $ ssh sshtron.zachlatta.com -_Controls: WASD or vim keybindings to move (**do not use your arrow keys**). Escape or Ctrl+C to exit._ +Controls: WASD or vim keybindings to move (**do not use your arrow keys**). Escape or Ctrl+C to exit. + + +Code quality disclaimer: SSHTron was built in ~20 hours at BrickHack 2: https://brickhack.io/. Here be dragons. -![Demo](static/img/gameplay.gif) -**Code quality disclaimer:** _SSHTron was built in ~20 hours at [BrickHack 2](https://brickhack.io/). Here be dragons._ -## Want to choose color yourself? +Want to choose color yourself? +------------------------------ There are total 7 colors to choose from: Red, Green, Yellow, Blue, Magenta, Cyan and White @@ -18,11 +18,13 @@ There are total 7 colors to choose from: Red, Green, Yellow, Blue, Magenta, Cyan If the color you picked is already taken in all open games, you'll randomly be assigned a color. -## Running Your Own Copy + + +Running Your Own Copy +--------------------- Clone the project and `cd` into its directory. These instructions assume that you have your `GOPATH` setup correctly. -```sh # Create an RSA public/private keypair in the current directory for the server # to use. Don't give it a passphrase. $ ssh-keygen -t rsa -f id_rsa @@ -33,37 +35,42 @@ $ go get && go build # Run it! You can set PORT to customize the HTTP port it serves on and SSH_PORT # to customize the SSH port it serves on. $ ./sshtron -``` -## Running under a Docker container + + +Running under a Docker container +-------------------------------- Clone the project and `cd` into its directory. -```sh # Build the SSHTron Docker image $ docker build -t sshtron . # Spin up the container with always-restart policy $ docker run -t -d -p 2022:2022 --restart always --name sshtron sshtron -``` + For Raspberry Pi, use the following to build the Docker image: -```sh $ docker build -t sshtron --build-arg BASE_IMAGE=resin/raspberry-pi-golang:latest . -``` -## CVE-2016-0777 -[CVE-2016-0777](https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt) + +CVE-2016-0777 +------------- + +CVE-2016-0777: https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt revealed two SSH client vulnerabilities that can be exploited by a malicious SSH server. While SSHTron does not exploit these vulnerabilities, you should still patch your client before you play. SSHTron is open source, but the server could always be running a modified version of SSHTron that does exploit the vulnerabilities described -in [CVE-2016-0777](https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt). +in CVE-2016-0777 https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt + +If you haven't yet patched your SSH client, you can follow these instructions +https://www.jacobtomlinson.co.uk/quick%20tip/2016/01/15/fixing-ssh-vulnerability-CVE-2016-0777/ to do so now. + -If you haven't yet patched your SSH client, you can follow -[these instructions](https://www.jacobtomlinson.co.uk/quick%20tip/2016/01/15/fixing-ssh-vulnerability-CVE-2016-0777/) to do so now. -## License +License +------- -SSHTron is licensed under the MIT License. See the full license text in [`LICENSE`](LICENSE). +SSHTron is licensed under the MIT License. See the full license text in LICENSE @@ -10,7 +10,6 @@ import ( "strings" "time" - "github.com/dustinkirkland/golang-petname" "github.com/fatih/color" "golang.org/x/crypto/ssh" ) @@ -45,7 +44,7 @@ func (h *Hub) Run(g *Game) { h.Sessions[s] = struct{}{} case s := <-h.Unregister: if _, ok := h.Sessions[s]; ok { - fmt.Fprint(s, "\r\n\r\n~ End of Line ~ \r\n\r\nRemember to use WASD to move!\r\n\r\n") + fmt.Fprint(s, "\r\n\r\n~ Fin de línea ~ \r\n\r\nRecuerda que con WASD te mueves!\r\n\r\n") // Unhide the cursor fmt.Fprint(s, "\033[?25h") @@ -124,13 +123,13 @@ var playerBorderColors = map[color.Attribute]color.Attribute{ } var playerColorNames = map[color.Attribute]string{ - playerRed: "Red", - playerGreen: "Green", - playerYellow: "Yellow", - playerBlue: "Blue", + playerRed: "Rojo", + playerGreen: "Verde", + playerYellow: "Amarillo", + playerBlue: "Azul", playerMagenta: "Magenta", playerCyan: "Cyan", - playerWhite: "White", + playerWhite: "Blanco", } type PlayerTrailSegment struct { @@ -474,7 +473,7 @@ func (g *Game) initalizeLevel(width, height int) { } func (g *Game) setTileType(pos Position, tileType TileType) error { - outOfBoundsErr := "The given %s value (%s) is out of bounds" + outOfBoundsErr := "El valor %s de (%s) está fuera de límite" if pos.RoundX() > len(g.level) || pos.RoundX() < 0 { return fmt.Errorf(outOfBoundsErr, "X", pos.X) } else if pos.RoundY() > len(g.level[pos.RoundX()]) || pos.RoundY() < 0 { @@ -540,7 +539,7 @@ func (g *Game) worldString(s *Session) string { // Draw the player's score scoreStr := fmt.Sprintf( - " Score: %d : Your High Score: %d : Game High Score: %d ", + " Puntaje: %d : Tu mejor puntaje: %d : Mejor puntaje del juego: %d ", s.Player.Score(), s.HighScore, g.HighScore, @@ -590,7 +589,7 @@ func (g *Game) worldString(s *Session) string { strWorld[startX][len(strWorld[0])-1] = " " } else { warning := - " Warning: Other Players Must be in This Game for You to Score! " + " Advertencia: Debe haber otros jugadores en el juego para poder sumar puntos " for i, r := range warning { strWorld[3+i][len(strWorld[0])-1] = borderColorizer(string(r)) } @@ -744,7 +743,7 @@ func (g *Game) Update(delta float64) { // Kick the player if they've timed out if time.Now().Sub(session.LastAction) > playerTimeout { - fmt.Fprint(session, "\r\n\r\nYou were terminated due to inactivity\r\n") + fmt.Fprint(session, "\r\n\r\nSesión finalizada por inactividad\r\n") g.RemoveSession(session) return } @@ -2,11 +2,12 @@ package main import ( "fmt" - "golang.org/x/crypto/ssh" "io/ioutil" "net" "net/http" "os" + + "golang.org/x/crypto/ssh" ) const ( @@ -22,7 +23,7 @@ func handler(conn net.Conn, gm *GameManager, config *ssh.ServerConfig) { // net.Conn. sshConn, chans, reqs, err := ssh.NewServerConn(conn, config) if err != nil { - fmt.Println("Failed to handshake with new client") + fmt.Println("Error conectandose al nuevo cliente") return } // The incoming Request channel must be serviced. @@ -35,19 +36,19 @@ func handler(conn net.Conn, gm *GameManager, config *ssh.ServerConfig) { // "session" and ServerShell may be used to present a simple // terminal interface. if newChannel.ChannelType() != "session" { - newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") + newChannel.Reject(ssh.UnknownChannelType, "tipo de canal desconocido") continue } channel, requests, err := newChannel.Accept() if err != nil { - fmt.Println("could not accept channel.") + fmt.Println("no se pudo aceptar el canal") return } // TODO: Remove this -- only temporary while we launch on HN // // To see how many concurrent users are online - fmt.Printf("Player joined. Current stats: %d users, %d games\n", + fmt.Printf("Jugador agregado. Estado actual: %d usuarios, %d juegos\n", gm.SessionCount(), gm.GameCount()) // Reject all out of band requests accept for the unix defaults, pty-req and @@ -90,12 +91,12 @@ func main() { privateBytes, err := ioutil.ReadFile("id_rsa") if err != nil { - panic("Failed to load private key") + panic("No se pudo cargar la llave privada") } private, err := ssh.ParsePrivateKey(privateBytes) if err != nil { - panic("Failed to parse private key") + panic("No se pudo leer la llave privada") } config.AddHostKey(private) @@ -104,7 +105,7 @@ func main() { gm := NewGameManager() fmt.Printf( - "Listening on port %s for SSH and port %s for HTTP...\n", + "Escuchando en puerto %s de SSH y puerto %s de HTTP...\n", sshPort, httpPort, ) @@ -117,13 +118,13 @@ func main() { // accepted. listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0%s", sshPort)) if err != nil { - panic("failed to listen for connection") + panic("No se pudieron escuchar conexiones") } for { nConn, err := listener.Accept() if err != nil { - panic("failed to accept incoming connection") + panic("No se pudo aceptar conexion entrante") } go handler(nConn, gm, config) diff --git a/static/index.html b/static/index.html index e17ffde..7f0f1ee 100644 --- a/static/index.html +++ b/static/index.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html> <head> - <title>SSHTron - Tron in Your Terminal</title> + <title>SSHTron - Tron en tu Terminal</title> <meta charset="utf-8"> <meta name="viewport" content="width=720, initial-scale=1"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,800,700|Kalam|VT323" @@ -15,7 +15,7 @@ href="favicon.png"> <!-- Open Graph meta tags --> <meta property="og:description" - content="SSHTron is a multiplayer Tron game through SSH in your terminal."> + content="SSHTron es un juego de Tron multijugador a través de SSH en tu terminal."> <meta property="og:image" content="http://sshtron.zachlatta.com/img/logo.jpg"> <meta property="og:title" content="SSHTron"> <meta property="og:type" content="website"> @@ -25,36 +25,15 @@ <h1 class="title">SSH Tron</h1> <div class="container"> <p class="description"> - Multiplayer Tron in your terminal. Just run the command below and you'll - be playing in seconds. + Tron multijugador en tu terminal. Usa el comando descripto más abajo y podrás jugar. </p> <p class="description"><code><span class="no-copy">$</span> ssh sshtron.zachlatta.com</code></p> - <p class="subtext">(WASD or vim keybindings for movement, <b>do not use arrow keys</b>)</p> + <p class="subtext">(WASD or teclas de vim para moverse, <b>no uses las flechas!</b>)</p> <img class="gameplay-image" src="/img/gameplay.gif"> <p class="subtext"> - By <a href="https://github.com/maxwofford">@MaxWofford</a> and - <a href="https://github.com/zachlatta">@zachlatta</a>. Check out - <a href="https://hackclub.com">Hack Club</a>, our new nonprofit. + Por <a href="https://github.com/maxwofford">@MaxWofford</a> y + <a href="https://github.com/zachlatta">@zachlatta</a>. Visita + <a href="https://hackclub.com">Hack Club</a>, nuestra nueva organización sin fines de lucro. </p> - - <div class="share-links"> - <div class="share-link fb-share-button" data-href="https://sshtron.zachlatta.com" data-layout="button"></div> - <a href="https://twitter.com/share" class="twitter-share-button"{count} data-text="SSHTron - Multiplayer Tron game played through SSH">Tweet</a> - </div> - <!-- Social buttons --> - <div id="fb-root"></div> - <script> (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; - if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; - js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.5"; - fjs.parentNode.insertBefore(js, fjs); }(document, 'script', - 'facebook-jssdk'));</script> - <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> - <!-- Segment --> - <script> - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; - analytics.load("pRYYOcXEHeMZtd3oazxcqAmipRo4wWgb"); - analytics.page(); - }}(); - </script> </body> </html> |