From 5d3ab3dcf8deb887877523e0293237bcee804b1b Mon Sep 17 00:00:00 2001
From: stale <redkugelblitzin@gmail.com>
Date: Wed, 11 May 2022 07:00:55 -0300
Subject: Ported, it woooorks

---
 Cargo.lock   | 393 +++++++++++++++++++++++++++++++++++++++++++----------------
 Cargo.toml   |  11 +-
 page.html    |   4 +-
 src/conn.rs  | 133 ++++----------------
 src/main.rs  | 145 +++++++---------------
 src/types.rs |  15 ++-
 6 files changed, 375 insertions(+), 326 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 00bb05a..1f200e3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,12 +2,6 @@
 # It is not intended for manual editing.
 version = 3
 
-[[package]]
-name = "anyhow"
-version = "1.0.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
-
 [[package]]
 name = "autocfg"
 version = "1.1.0"
@@ -26,6 +20,15 @@ version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "block-buffer"
 version = "0.10.2"
@@ -35,6 +38,16 @@ dependencies = [
  "generic-array",
 ]
 
+[[package]]
+name = "buf_redux"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
+dependencies = [
+ "memchr",
+ "safemem",
+]
+
 [[package]]
 name = "bumpalo"
 version = "3.9.1"
@@ -84,16 +97,34 @@ dependencies = [
  "typenum",
 ]
 
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "digest"
 version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
 dependencies = [
- "block-buffer",
+ "block-buffer 0.10.2",
  "crypto-common",
 ]
 
+[[package]]
+name = "fastrand"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+dependencies = [
+ "instant",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -110,41 +141,6 @@ dependencies = [
  "percent-encoding",
 ]
 
-[[package]]
-name = "format-bytes"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48942366ef93975da38e175ac9e10068c6fc08ca9e85930d4f098f4d5b14c2fd"
-dependencies = [
- "format-bytes-macros",
-]
-
-[[package]]
-name = "format-bytes-macros"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "203aadebefcc73d12038296c228eabf830f99cba991b0032adf20e9fa6ce7e4f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
 [[package]]
 name = "futures-channel"
 version = "0.3.21"
@@ -161,23 +157,6 @@ version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
 
-[[package]]
-name = "futures-executor"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
-
 [[package]]
 name = "futures-macro"
 version = "0.3.21"
@@ -207,13 +186,10 @@ version = "0.3.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
 dependencies = [
- "futures-channel",
  "futures-core",
- "futures-io",
  "futures-macro",
  "futures-sink",
  "futures-task",
- "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
@@ -255,7 +231,7 @@ dependencies = [
  "indexmap",
  "slab",
  "tokio",
- "tokio-util",
+ "tokio-util 0.7.1",
  "tracing",
 ]
 
@@ -265,6 +241,31 @@ version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
 
+[[package]]
+name = "headers"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
+dependencies = [
+ "base64",
+ "bitflags",
+ "bytes",
+ "headers-core",
+ "http",
+ "httpdate",
+ "mime",
+ "sha-1 0.10.0",
+]
+
+[[package]]
+name = "headers-core"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+dependencies = [
+ "http",
+]
+
 [[package]]
 name = "hermit-abi"
 version = "0.1.19"
@@ -332,19 +333,6 @@ dependencies = [
  "want",
 ]
 
-[[package]]
-name = "hyper-tungstenite"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0ea2c1b59596d6b1302fe616266257a58b079f68fee329d6d111f79241cb7fd"
-dependencies = [
- "hyper",
- "pin-project",
- "tokio",
- "tokio-tungstenite",
- "tungstenite",
-]
-
 [[package]]
 name = "idna"
 version = "0.2.3"
@@ -366,6 +354,15 @@ dependencies = [
  "hashbrown",
 ]
 
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "itoa"
 version = "1.0.1"
@@ -424,6 +421,22 @@ version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
 [[package]]
 name = "mio"
 version = "0.8.2"
@@ -447,6 +460,24 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "multipart"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182"
+dependencies = [
+ "buf_redux",
+ "httparse",
+ "log",
+ "mime",
+ "mime_guess",
+ "quick-error",
+ "rand",
+ "safemem",
+ "tempfile",
+ "twoway",
+]
+
 [[package]]
 name = "ntapi"
 version = "0.3.7"
@@ -472,6 +503,12 @@ version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
 
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
 [[package]]
 name = "parking_lot"
 version = "0.12.0"
@@ -548,6 +585,12 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
 [[package]]
 name = "quote"
 version = "1.0.18"
@@ -596,6 +639,15 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
 [[package]]
 name = "ring"
 version = "0.16.20"
@@ -613,10 +665,11 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.20.4"
+version = "0.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921"
+checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
 dependencies = [
+ "base64",
  "log",
  "ring",
  "sct",
@@ -624,13 +677,22 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustls-pemfile"
+name = "ryu"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+
+[[package]]
+name = "safemem"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+
+[[package]]
+name = "scoped-tls"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
-dependencies = [
- "base64",
-]
+checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
 
 [[package]]
 name = "scopeguard"
@@ -640,14 +702,56 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "sct"
-version = "0.7.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
 dependencies = [
  "ring",
  "untrusted",
 ]
 
+[[package]]
+name = "serde"
+version = "1.0.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+
+[[package]]
+name = "serde_json"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.9.0",
+ "opaque-debug",
+]
+
 [[package]]
 name = "sha-1"
 version = "0.10.0"
@@ -656,7 +760,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
 dependencies = [
  "cfg-if",
  "cpufeatures",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -707,6 +811,20 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
 [[package]]
 name = "thiserror"
 version = "1.0.31"
@@ -775,27 +893,53 @@ dependencies = [
 
 [[package]]
 name = "tokio-rustls"
-version = "0.23.4"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
 dependencies = [
  "rustls",
  "tokio",
  "webpki",
 ]
 
+[[package]]
+name = "tokio-stream"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
 [[package]]
 name = "tokio-tungstenite"
-version = "0.17.1"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae"
+checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8"
 dependencies = [
  "futures-util",
  "log",
+ "pin-project",
  "tokio",
  "tungstenite",
 ]
 
+[[package]]
+name = "tokio-util"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite",
+ "tokio",
+]
+
 [[package]]
 name = "tokio-util"
 version = "0.7.1"
@@ -823,6 +967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
 dependencies = [
  "cfg-if",
+ "log",
  "pin-project-lite",
  "tracing-attributes",
  "tracing-core",
@@ -856,9 +1001,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 
 [[package]]
 name = "tungstenite"
-version = "0.17.2"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
+checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5"
 dependencies = [
  "base64",
  "byteorder",
@@ -867,18 +1012,36 @@ dependencies = [
  "httparse",
  "log",
  "rand",
- "sha-1",
+ "sha-1 0.9.8",
  "thiserror",
  "url",
  "utf-8",
 ]
 
+[[package]]
+name = "twoway"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "typenum"
 version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
 
+[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+dependencies = [
+ "version_check",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.8"
@@ -940,6 +1103,37 @@ dependencies = [
  "try-lock",
 ]
 
+[[package]]
+name = "warp"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "headers",
+ "http",
+ "hyper",
+ "log",
+ "mime",
+ "mime_guess",
+ "multipart",
+ "percent-encoding",
+ "pin-project",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tokio-tungstenite",
+ "tokio-util 0.6.9",
+ "tower-service",
+ "tracing",
+]
+
 [[package]]
 name = "wasi"
 version = "0.10.2+wasi-snapshot-preview1"
@@ -1018,9 +1212,9 @@ dependencies = [
 
 [[package]]
 name = "webpki"
-version = "0.22.0"
+version = "0.21.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
 dependencies = [
  "ring",
  "untrusted",
@@ -1030,17 +1224,10 @@ dependencies = [
 name = "websweeper"
 version = "1.0.0"
 dependencies = [
- "anyhow",
- "format-bytes",
- "futures",
- "futures-channel",
  "futures-util",
- "hyper",
- "hyper-tungstenite",
  "rand",
- "rustls-pemfile",
  "tokio",
- "tokio-rustls",
+ "warp",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index d54c86d..1cfddc5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,14 +7,7 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-hyper = { version = "0.14", features = ["full"] }
 tokio = { version = "1", features = ["full"] }
-tokio-rustls = "0.23"
-rustls-pemfile = "1"
-hyper-tungstenite = "0.8"
+warp = { version = "0.3", features = ["tls", "websocket"] }
 rand = "0.8"
-futures = "0.3"
-futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
-futures-channel = "0.3"
-format-bytes = "0.3"
-anyhow = "1.0"
+futures-util = "0.3"
diff --git a/page.html b/page.html
index e2aec9b..78df322 100644
--- a/page.html
+++ b/page.html
@@ -11,11 +11,11 @@
     src: url("font.ttf");
 }
     #board-container {
-      font-family: vt323, monospace;
       font-size: 28pt;
       line-height: 0.6em;
     }
     body {
+      font-family: vt323, monospace;
       background-color: black;
       color: white;
     }
@@ -46,7 +46,7 @@
   <script>
     window.id = NaN;
     let wsproto = (window.location.protocol == "https:")? "wss:": "ws:";
-    let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}`);
+    let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}/ws`);
     let info_elem = document.getElementById("miscinfo");
     let board_elem = document.getElementById("board");
     let name = "deadbeef";
diff --git a/src/conn.rs b/src/conn.rs
index 6d08942..fda3a2b 100644
--- a/src/conn.rs
+++ b/src/conn.rs
@@ -1,106 +1,19 @@
 use crate::types::*;
-use std::{
-    net::SocketAddr,
-    convert::Infallible,
-    pin::Pin,
-    task::Poll,
-};
-use hyper::{ Request, Response, Body, service::Service };
-use hyper_tungstenite::{
-    HyperWebsocket,
-    tungstenite::Message,
-};
-use futures::{
-    Future,
-    SinkExt,
-    StreamExt,
-    TryStreamExt,
-    TryFuture,
-    TryFutureExt,
-    channel::mpsc::unbounded,
-    pin_mut,
-};
+use futures_util::{SinkExt, StreamExt, TryStreamExt};
+use warp::ws::Message;
 
-const FONT_FILE: &[u8] = include_bytes!("./VT323-Regular.ttf");
-
-#[derive(Clone)]
-pub struct PerConnHandler {
-    pub state: State,
-    pub local_addr: SocketAddr,
-    pub remote_addr: SocketAddr,
-    pub game_cmd_tx: MovReqTx,
-    pub page: String,
-}
-
-impl PerConnHandler {
-    async fn handle_req(self, req: Request<Body>)
-        -> std::result::Result<Response<Body>, Infallible>
-    {
-        if hyper_tungstenite::is_upgrade_request(&req) {
-            let (resp, wsocket) = hyper_tungstenite::upgrade(req, None).expect("couldn't upgrade to websocket");
-            tokio::spawn(async move {
-                peer_connection(self, wsocket).await;
-            });
-            return Ok(resp);
-        }
-
-        //let page = tokio::fs::read_to_string(self.page).await.map_err(errpage)?;
-        let mut uri_path = req.uri().path().split('/').skip(1);
-        let actual_path = uri_path.next();
-
-        use hyper::{ Method, StatusCode };
-        match (req.method(), actual_path) {
-            (&Method::GET, None | Some("")) => {
-                Ok(Response::builder()
-                    .status(StatusCode::OK)
-                    .body(Body::from(self.page))
-                    .unwrap())
-            },
-            (&Method::GET, Some("font.ttf")) => {
-                Ok(Response::builder()
-                    .status(StatusCode::OK)
-                    .body(Body::from(FONT_FILE))
-                    .unwrap())
-            },
-            _ => {
-                Ok(Response::builder()
-                    .status(StatusCode::NOT_FOUND)
-                    .body(Body::empty())
-                    .unwrap())
-            }
-        }
-    }
-}
-
-impl Service<Request<Body>> for PerConnHandler
-{
-    type Response = Response<Body>;
-    type Error = Infallible;
-    type Future = Pin<Box<dyn Future<Output = std::result::Result<Self::Response,Self::Error>> + Send>>;
-
-    fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
-        Poll::Ready(Ok(()))
-    }
-
-    fn call(&mut self, req: Request<Body>) -> Self::Future {
-        let cloned_self = self.clone();
-        Box::pin(cloned_self.handle_req(req))
-    }
-}
-
-pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
-    let socket = socket.await.expect("couldn't finish websocket connection");
-    let addr = conn.remote_addr;
-    let peers = &conn.state.peers;
-    let mut cmd_tx = &conn.game_cmd_tx;
-    println!("Incoming TCP connection from: {addr}");
+pub async fn peer_connection(socket: warp::ws::WebSocket, conndata: ConnData) {
+    let addr = conndata.remote_addr;
+    let peers = &conndata.peers;
+    let cmd_tx = conndata.cmd_tx.clone();
+    println!("Incoming TCP connection from: {}", conndata.remote_addr);
 
     let mut peer_name = "unknown".to_string();
 
     // for game -> conn comms
-    let (tx, rx) = unbounded();
+    let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
     // for server -> client comms
-    let (outgoing, mut incoming) = socket.split();
+    let (mut outgoing, mut incoming) = socket.split();
 
     let process_incoming = async {
         while let Ok(cmd) = incoming.try_next().await {
@@ -112,7 +25,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                         peers.remove(&addr);
                     }
                     for (paddr, p) in peers.iter() {
-                        if let Err(e) = tx.unbounded_send(Message::text("logoff {p.seqid} {p.name}")) {
+                        if let Err(e) = tx.send(Message::text("logoff {p.seqid} {p.name}")) {
                             println!("couldn't deliver logoff info to \"{}\"@{}: {}", p.name, paddr, e);
                         }
                     }
@@ -120,7 +33,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                 }
                 // if it ain't text we can't handle it
                 if !cmd.is_text() { continue; }
-                let cmd = cmd.to_text().unwrap();
+                let cmd = cmd.to_str().to_owned().unwrap();
 
                 let mut fields = cmd.split(" ");
                 let parse_pos = |mut fields: std::str::Split<&str>| -> Option<(usize, usize)> {
@@ -144,7 +57,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                                     {
                                         let peers = peers.read().await;
                                         for peer_tx in peers.iter().filter(|(s, _)| **s != addr).map(|(_,p)| &p.tx) {
-                                            let r = peer_tx.unbounded_send(Message::text(format!("pos {id} {sanitized_name} {} {}", pos.0, pos.1)));
+                                            let r = peer_tx.send(Message::text(format!("pos {id} {sanitized_name} {} {}", pos.0, pos.1)));
                                             if let Err(e) = r {
                                                 println!("error sending pos update: {e}");
                                             }
@@ -160,7 +73,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                             match parse_pos(fields) {
                                 Some(pos) => {
                                     println!("{cmd} from \"{peer_name}\"@{addr}");
-                                    if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::Reveal, pos }, addr)).await {
+                                    if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::Reveal, pos }, addr)) {
                                         println!("couldn't process \"{peer_name}\"'s reveal command: {e}");
                                     };
                                 },
@@ -173,7 +86,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                             match parse_pos(fields) {
                                 Some(pos) => {
                                     println!("{cmd} from \"{peer_name}\"@{addr}");
-                                    if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::ToggleFlag, pos }, addr)).await {
+                                    if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::ToggleFlag, pos }, addr)) {
                                         println!("couldn't process \"{peer_name}\"'s flag command: {e}");
                                     };
                                 },
@@ -184,7 +97,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                         },
                         "reset" => {
                             println!("{cmd} from \"{peer_name}\"@{addr}");
-                            if let Err(e) = cmd_tx.send(MetaMove::Reset).await {
+                            if let Err(e) = cmd_tx.send(MetaMove::Reset) {
                                 println!("couldn't send game dump to \"{peer_name}\"@{addr}: {e}");
                             }
                         },
@@ -206,8 +119,8 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
                                     position: (0,0)
                                 });
                             }
-                            tx.unbounded_send(Message::text(format!("id {id}"))).unwrap();
-                            if let Err(e) = cmd_tx.send(MetaMove::Dump).await {
+                            tx.send(Message::text(format!("id {id}"))).unwrap();
+                            if let Err(e) = cmd_tx.send(MetaMove::Dump) {
                                 println!("couldn't send game dump to \"{peer_name}\"@{addr}: {e}");
                             }
                         },
@@ -217,10 +130,16 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
             }
         }
     };
-    let send_to_browser = rx.map(Ok).forward(outgoing);
+    let send_to_client = async move {
+        while let Some(m) = rx.recv().await {
+            if let Err(e) = outgoing.send(m).await {
+                println!("something went bad lol: {e}");
+            };
+        }
+    };
 
-    pin_mut!(process_incoming, send_to_browser);
-    futures_util::future::select(process_incoming, send_to_browser).await;
+    futures_util::pin_mut!(process_incoming, send_to_client);
+    futures_util::future::select(process_incoming, send_to_client).await;
 
     println!("{addr} disconnected");
     peers.write().await.remove(&addr);
diff --git a/src/main.rs b/src/main.rs
index cafc9d4..b3c3cf9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,33 +1,21 @@
-#[macro_use] extern crate anyhow;
-
-pub use anyhow::{ Result, Error };
-
 use std::{
     convert::Infallible,
     collections::HashMap,
+    error::Error,
     net::SocketAddr,
-    sync::Arc,
 };
+use warp::Filter;
 
 mod types;
 mod conn;
 mod minesweeper;
 use types::*;
 
-use hyper::{ Body, Request, Server };
-use hyper::server::conn::{ AddrStream, AddrIncoming };
-use hyper::service::{make_service_fn, service_fn, Service};
 use tokio::sync::RwLock;
-use std::fs;
-
-use futures_util::{future, pin_mut, ready, stream::TryStreamExt, StreamExt, sink::SinkExt, TryFutureExt};
 
-use hyper_tungstenite::{ tungstenite::protocol::Message, HyperWebsocket };
-use tokio_rustls::{ rustls, Accept, server::TlsStream, TlsAcceptor };
-use rustls::{ServerConnection, SupportedCipherSuite, ProtocolVersion, ServerConfig,
-             Certificate, PrivateKey};
+const FONT_FILE: &[u8] = include_bytes!("./VT323-Regular.ttf");
 
-fn main() -> Result<()> {
+fn main() -> Result<(), Box<dyn Error>> {
     let conf = Config {
         cert_path: "./cert.pem".to_owned(),
         pkey_path: "./cert.rsa".to_owned(),
@@ -40,91 +28,59 @@ fn main() -> Result<()> {
         peers: PeerMap::new(RwLock::new(HashMap::new())),
     };
 
-    let cert_pem = fs::read(&state.conf.cert_path)?;
-    let pkey_pem = fs::read(&state.conf.pkey_path)?;
+    tokio_main(state)
+}
 
-    // Build TLS configuration.
-    let tls_cfg = {
-        let certs: Vec<Certificate> = rustls_pemfile::certs(&mut &*cert_pem)
-            .map(|mut certs| certs.drain(..).map(Certificate).collect())?;
-        if certs.len() < 1 {
-            return Err(anyhow!("No certificates found"));
-        }
-        let mut keys: Vec<PrivateKey> = rustls_pemfile::rsa_private_keys(&mut &*pkey_pem)
-            .map(|mut keys| keys.drain(..).map(PrivateKey).collect())?;
-        if keys.len() < 1 {
-            return Err(anyhow!("No private keys found"));
-        }
+#[tokio::main]
+async fn tokio_main(state: State) -> Result<(), Box<dyn Error>> {
+    // Start the temporary single lobby
+    let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel();
+    let _game_t = tokio::spawn(gameloop(cmd_rx, state.peers.clone()));
 
-        let mut tls_cfg = ServerConfig::builder()
-            .with_safe_defaults()
-            .with_no_client_auth()
-            .with_single_cert(certs, keys.remove(0))?;
+    let cmd_filter = warp::any().map(move || cmd_tx.clone());
 
-        // Configure ALPN to accept HTTP/2, HTTP/1.1 in that order.
-        tls_cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
-        tls_cfg
+    let page_route = {
+        use warp::*;
+        get()
+        .and(path("font.ttf"))
+        .map(|| FONT_FILE)
+        .or(fs::file(state.conf.page_path.clone()))
     };
 
-    tokio_main(state, tls_cfg)
-}
+    let websocket_route = {
+        let state = state.clone();
+        use warp::*;
+        path("ws")
+            .and(ws())
+            .and(addr::remote())
+            .and(cmd_filter)
+            .map(move |ws: warp::ws::Ws, saddr: Option<SocketAddr>, cmd_tx: CmdTx| {
+                let state = state.clone();
+                println!("conn from {saddr:?}");
+                ws.on_upgrade(move |socket| {
+                    let conn_data = types::ConnData { remote_addr: saddr.unwrap(), cmd_tx: cmd_tx.clone(), peers: state.peers.clone() };
+                    conn::peer_connection(socket, conn_data)
+                })
+            })
+    };
+    let routes = websocket_route.or(page_route);
 
-#[tokio::main]
-async fn tokio_main(state: State, tls_conf: ServerConfig) -> Result<()> {
-    let server = main_server(state.clone(), tls_conf);
+    let server = warp::serve(routes)
+        .tls()
+        .cert_path(state.conf.cert_path)
+        .key_path(state.conf.pkey_path)
+        .run(state.conf.socket_addr);
     println!("Serving on {}", state.conf.socket_addr);
-    server.await?;
+    server.await;
     Ok(())
 }
 
-async fn main_server(state: State, tls_conf: ServerConfig) -> Result<()> {
-    // Create a TCP listener, that uses TLS
-    let listener = tokio::net::TcpListener::bind(&state.conf.socket_addr).await?;
-    let local_addr = listener.local_addr()?;
-    let acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(tls_conf));
-    let http = hyper::server::conn::Http::new();
-
-    // Start the temporary single lobby
-    let (cmd_tx, cmd_rx) = futures::channel::mpsc::unbounded();
-    let game_t = tokio::spawn(gameloop(cmd_rx, state.peers.clone()));
-
-    loop {
-        let (conn, remote_addr) = listener.accept().await?;
-        let acceptor = acceptor.clone();
-        let http = http.clone();
-        let cloned_state = state.clone();
-        let cmd_tx = cmd_tx.clone();
-        let fut = async move {
-            match acceptor.accept(conn).await {
-                Ok(stream) => {
-                    let page = tokio::fs::read_to_string(&cloned_state.conf.page_path).await;
-                    if let Err(e) = page { return Err(anyhow!("couldn't read page file: {e}")); }
-
-                    let handler = conn::PerConnHandler {
-                        state: cloned_state,
-                        local_addr,
-                        remote_addr,
-                        game_cmd_tx: cmd_tx,
-                        page: page.unwrap(),
-                    };
-                    if let Err(e) = http.serve_connection(stream, handler).await {
-                        eprintln!("hyper error for {remote_addr}: {e}");
-                    }
-                },
-                Err(e) => eprintln!("TLS error for {remote_addr}: {e}"),
-            }
-            Ok(())
-        };
-        tokio::spawn(fut);
-    }
-}
-
 // If a move is made, broadcast new board, else just send current board
-async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMove>, peers: PeerMap) {
+async fn gameloop(mut move_rx: tokio::sync::mpsc::UnboundedReceiver<MetaMove>, peers: PeerMap) {
     use minesweeper::*;
     let mut game = Game::new(Board::new(75,35), (75*35)/8);
     let mut latest_player_name = None;
-    while let Some(req) = move_rx.next().await {
+    while let Some(req) = move_rx.recv().await {
         let done = game.phase == Phase::Die || game.phase == Phase::Win;
         match req {
             MetaMove::Move(m, o) => if !done {
@@ -137,6 +93,7 @@ async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMov
             MetaMove::Dump => (),
             MetaMove::Reset => { game = Game::new(Board::new(75,35), (75*35)/8); },
         }
+        use warp::ws::Message;
         let mut reply = vec![Message::binary(game.board.render())];
         let lpname = latest_player_name.as_ref().map(|s| s.as_str()).unwrap_or("unknown player");
         match game.phase {
@@ -148,21 +105,11 @@ async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMov
             let peers = peers.read().await;
             for (addr, p) in peers.iter() {
                 for r in reply.iter() {
-                    if let Err(e) = p.tx.unbounded_send(r.clone()) {
-                        println!("couldn't send game update {r} to {addr}: {e}");
+                    if let Err(e) = p.tx.send(r.clone()) {
+                        println!("couldn't send game update {r:?} to {addr}: {e}");
                     }
                 }
             }
         }
     }
 }
-
-fn error(err: String) -> std::io::Error {
-    std::io::Error::new(std::io::ErrorKind::Other, err)
-}
-
-async fn shutdown_signal() {
-    tokio::signal::ctrl_c()
-        .await
-        .expect("failed to install CTRL+C signal handler");
-}
diff --git a/src/types.rs b/src/types.rs
index eed69dd..73d51b8 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -3,10 +3,8 @@ use std::{
     net::SocketAddr,
     sync::Arc,
 };
+use warp::ws::Message;
 use tokio::sync::RwLock;
-use hyper_tungstenite::tungstenite::Message;
-use hyper::{ Response, Body };
-use futures::channel::mpsc::UnboundedSender;
 use crate::minesweeper;
 
 #[derive(Debug, Clone)]
@@ -32,12 +30,17 @@ pub enum MetaMove {
 
 #[derive(Debug)]
 pub struct Peer {
-    pub tx: UnboundedSender<Message>,
+    pub tx: tokio::sync::mpsc::UnboundedSender<Message>,
     pub seq_id: usize,
     pub name: String,
     pub position: (usize, usize),
 }
 
-pub type HtmlResult = Result<Response<Body>, Response<Body>>;
-pub type MovReqTx = futures::channel::mpsc::UnboundedSender<MetaMove>;
+pub struct ConnData {
+    pub cmd_tx: CmdTx,
+    pub remote_addr: SocketAddr,
+    pub peers: PeerMap,
+}
+
+pub type CmdTx = tokio::sync::mpsc::UnboundedSender<MetaMove>;
 pub type PeerMap = Arc<RwLock<HashMap<SocketAddr, Peer>>>;
-- 
cgit v1.2.3