From 0ed316cb5ea918a44a03f05c3161766a49800977 Mon Sep 17 00:00:00 2001 From: Akilan Selvacoumar Date: Sun, 10 Oct 2021 00:09:37 +0400 Subject: [PATCH] support for x2x and barrier KVM --- README.md | 28 +- config/config.go | 42 +- config/config_test.go | 5 +- core/barrier-kvm.go | 23 +- core/names-generator.go | 972 ++++++++++++++++++++-------------------- core/room.go | 175 ++++---- core/signal.go | 336 +++++++------- files/main.html | 33 +- go.mod | 2 +- main.go | 19 +- run.sh | 10 +- 11 files changed, 831 insertions(+), 814 deletions(-) diff --git a/README.md b/README.md index d15eefd..348842d 100644 --- a/README.md +++ b/README.md @@ -24,15 +24,31 @@ https://github.com/Akilan1999/laplace/tree/keyboard_mouse ### Installation required to share keyboard and mouse -We need to ensure that the client has SSH client installed. -We use the popular open repository known as [x2x](https://github.com/dottedmag/x2x). - -Note: x2x runs on top of SSH. +Currently, you can either use [x2x](https://github.com/dottedmag/x2x) or [Barrier KVM]() +We need to ensure that the client has SSH client installed or Barrierc. #### What is x2x? x2x allows the keyboard, mouse on one X display to be used to control another X display. It also shares X clipboards between the displays. +Note: x2x runs on top of SSH. + +#### What is Barrier kvm? + +Barrier is software that mimics the functionality of a KVM switch, which historically would allow you to use a single +keyboard and mouse to control multiple computers by physically turning a dial on the box to switch the machine you're +controlling at any given moment. Barrier does this in software, allowing you to tell it which machine to control by +moving your mouse to the edge of the screen, or by using a keypress to switch focus to a different system. + +#### Barrier KVM build status and links to install +|Platform |Build Status| +| --:|:-- | +|Linux |[![Build Status](https://dev.azure.com/debauchee/Barrier/_apis/build/status/debauchee.barrier?branchName=master&jobName=Linux%20Build)](https://dev.azure.com/debauchee/Barrier/_build/latest?definitionId=1&branchName=master)| +|Mac |[![Build Status](https://dev.azure.com/debauchee/Barrier/_apis/build/status/debauchee.barrier?branchName=master&jobName=Mac%20Build)](https://dev.azure.com/debauchee/Barrier/_build/latest?definitionId=1&branchName=master)| +|Windows Debug |[![Build Status](https://dev.azure.com/debauchee/Barrier/_apis/build/status/debauchee.barrier?branchName=master&jobName=Windows%20Build&configuration=Windows%20Build%20Debug)](https://dev.azure.com/debauchee/Barrier/_build/latest?definitionId=1&branchName=master)| +|Windows Release|[![Build Status](https://dev.azure.com/debauchee/Barrier/_apis/build/status/debauchee.barrier?branchName=master&jobName=Windows%20Build&configuration=Windows%20Build%20Release%20with%20Release%20Installer)](https://dev.azure.com/debauchee/Barrier/_build/latest?definitionId=1&branchName=master)| +|Snap |[![Snap Status](https://build.snapcraft.io/badge/debauchee/barrier.svg)](https://build.snapcraft.io/user/debauchee/barrier)| + ### Build from source @@ -51,6 +67,8 @@ apt install -y git apt install -y openssh-server ## Installing x2x apt install -y x2x +## Installing barrier +apt install -y barrier ## Installing chromium wget https://github.com/RobRich999/Chromium_Clang/releases/download/v94.0.4585.0-r904940-linux64-deb-avx/chromium-browser-unstable_94.0.4585.0-1_amd64.deb apt install -y ./chromium-browser-unstable_94.0.4585.0-1_amd64.deb @@ -117,11 +135,13 @@ cd /path/.local/share/Steam/steamapps/common/X-Plane\ 11/ ``` #### Open config file ```bash + { "barrierhostname": "", "ipaddress": "0.0.0.0", "rooms": "", "scripttoexecute": "", + "sshpassword": "", "systemusername": "" } ``` diff --git a/config/config.go b/config/config.go index f4ef3f7..618ffeb 100644 --- a/config/config.go +++ b/config/config.go @@ -8,23 +8,23 @@ import ( var ( defaultPath string - defaults = map[string]interface{}{ - "SystemUsername": "", + defaults = map[string]interface{}{ + "SystemUsername": "", "BarrierHostName": "", } - configName = "config" - configType = "json" - configFile = "config.json" + configName = "config" + configType = "json" + configFile = "config.json" configPaths []string ) type Config struct { - SystemUsername string - BarrierHostName string - Rooms string - IPAddress string - ScriptToExecute string - SSHPassword string + SystemUsername string + BarrierHostName string + Rooms string + IPAddress string + ScriptToExecute string + SSHPassword string } // Exists reports whether the named file or directory exists. @@ -47,7 +47,7 @@ func SetDefaults() error { defaultPath = curDir + "/" // Get system username - user ,err := user.Current() + user, err := user.Current() if err != nil { return err } @@ -59,8 +59,8 @@ func SetDefaults() error { } //Setting default paths for the config file - defaults["SystemUsername"] = user.Username - defaults["BarrierHostName"] = name + defaults["SystemUsername"] = user.Username + defaults["BarrierHostName"] = name defaults["Rooms"] = defaultPath + "room.json" defaults["IPAddress"] = "0.0.0.0" defaults["ScriptToExecute"] = "" @@ -88,7 +88,7 @@ func SetDefaults() error { return nil } -func ConfigInit()(*Config,error) { +func ConfigInit() (*Config, error) { curDir := os.Getenv("REMOTEGAMING") //Setting current directory to default path @@ -97,7 +97,7 @@ func ConfigInit()(*Config,error) { configPaths = append(configPaths, defaultPath) //Add all possible configurations paths - for _,v := range configPaths { + for _, v := range configPaths { viper.AddConfigPath(v) } @@ -105,23 +105,23 @@ func ConfigInit()(*Config,error) { if err := viper.ReadInConfig(); err != nil { // If the error thrown is config file not found //Sets default configuration to viper - for k,v := range defaults { - viper.SetDefault(k,v) + for k, v := range defaults { + viper.SetDefault(k, v) } viper.SetConfigName(configName) viper.SetConfigFile(configFile) viper.SetConfigType(configType) if err = viper.WriteConfig(); err != nil { - return nil,err + return nil, err } } // Adds configuration to the struct var config Config if err := viper.Unmarshal(&config); err != nil { - return nil,err + return nil, err } - return &config,nil + return &config, nil } diff --git a/config/config_test.go b/config/config_test.go index 4142e39..fe9e9c8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,4 +1,3 @@ - package config import ( @@ -6,7 +5,7 @@ import ( ) func TestConfigInit(t *testing.T) { - _,err := ConfigInit() + _, err := ConfigInit() if err != nil { t.Error(err) } @@ -17,4 +16,4 @@ func TestSetDefaults(t *testing.T) { if err != nil { t.Error(err) } -} \ No newline at end of file +} diff --git a/core/barrier-kvm.go b/core/barrier-kvm.go index 231acf8..653c72e 100644 --- a/core/barrier-kvm.go +++ b/core/barrier-kvm.go @@ -5,20 +5,20 @@ package core import ( - "laplace/config" + "github.com/Akilan1999/remotegameplay/config" "os/exec" ) // Barrier It's preferred that the IP address used is a IPV6 address type Barrier struct { - NodeName string - IPAddress string - Mode string - Process *exec.Cmd + NodeName string + IPAddress string + Mode string + Process *exec.Cmd } // CreateBarrierSession Command to run "barrier.barrierc --debug INFO -f 192.168.0.175" -func (b *Barrier)CreateBarrierSession() error { +func (b *Barrier) CreateBarrierSession() error { //Checks if barrier client exists if err := DetectBarrier(); err != nil { @@ -31,7 +31,7 @@ func (b *Barrier)CreateBarrierSession() error { return err } - cmd := exec.Command("sudo","-u",configResp.SystemUsername,"barrierc","-f","--debug", "DEBUG" ,"--log", "/tmp/barrier.log",b.IPAddress) + cmd := exec.Command("sudo", "-u", configResp.SystemUsername, "barrierc", "-f", "--debug", "DEBUG", "--log", "/tmp/barrier.log", b.IPAddress) // USE THE FOLLOWING TO DEBUG //cmdReader, err := cmd.StdoutPipe() @@ -62,18 +62,17 @@ func (b *Barrier)CreateBarrierSession() error { println(cmd.Path) - // Saves the state of the command in the struct b.Process = cmd return nil } // DeleteBarrierSession Deletes barrier client session running -func (b *Barrier)DeleteBarrierSession() error { +func (b *Barrier) DeleteBarrierSession() error { // Halts the process - cmd := exec.Command("pkill" ,"barrierc") + cmd := exec.Command("pkill", "barrierc") if err := cmd.Run(); err != nil { - return err + return err } return nil @@ -86,4 +85,4 @@ func DetectBarrier() error { return err } return nil -} \ No newline at end of file +} diff --git a/core/names-generator.go b/core/names-generator.go index 2358c1e..7561937 100644 --- a/core/names-generator.go +++ b/core/names-generator.go @@ -1,497 +1,497 @@ package core import ( - "fmt" - "math/rand" + "fmt" + "math/rand" ) var ( - left = [...]string{ - "admiring", - "adoring", - "affectionate", - "agitated", - "amazing", - "angry", - "awesome", - "beautiful", - "blissful", - "bold", - "boring", - "brave", - "busy", - "charming", - "clever", - "cool", - "compassionate", - "competent", - "condescending", - "confident", - "cranky", - "crazy", - "dazzling", - "determined", - "distracted", - "dreamy", - "eager", - "ecstatic", - "elastic", - "elated", - "elegant", - "eloquent", - "epic", - "exciting", - "fervent", - "festive", - "flamboyant", - "focused", - "friendly", - "frosty", - "funny", - "gallant", - "gifted", - "goofy", - "gracious", - "great", - "happy", - "hardcore", - "heuristic", - "hopeful", - "hungry", - "infallible", - "inspiring", - "interesting", - "intelligent", - "jolly", - "jovial", - "keen", - "kind", - "laughing", - "loving", - "lucid", - "magical", - "mystifying", - "modest", - "musing", - "naughty", - "nervous", - "nice", - "nifty", - "nostalgic", - "objective", - "optimistic", - "peaceful", - "pedantic", - "pensive", - "practical", - "priceless", - "quirky", - "quizzical", - "recursing", - "relaxed", - "reverent", - "romantic", - "sad", - "serene", - "sharp", - "silly", - "sleepy", - "stoic", - "strange", - "stupefied", - "suspicious", - "sweet", - "tender", - "thirsty", - "trusting", - "unruffled", - "upbeat", - "vibrant", - "vigilant", - "vigorous", - "wizardly", - "wonderful", - "xenodochial", - "youthful", - "zealous", - "zen", - } + left = [...]string{ + "admiring", + "adoring", + "affectionate", + "agitated", + "amazing", + "angry", + "awesome", + "beautiful", + "blissful", + "bold", + "boring", + "brave", + "busy", + "charming", + "clever", + "cool", + "compassionate", + "competent", + "condescending", + "confident", + "cranky", + "crazy", + "dazzling", + "determined", + "distracted", + "dreamy", + "eager", + "ecstatic", + "elastic", + "elated", + "elegant", + "eloquent", + "epic", + "exciting", + "fervent", + "festive", + "flamboyant", + "focused", + "friendly", + "frosty", + "funny", + "gallant", + "gifted", + "goofy", + "gracious", + "great", + "happy", + "hardcore", + "heuristic", + "hopeful", + "hungry", + "infallible", + "inspiring", + "interesting", + "intelligent", + "jolly", + "jovial", + "keen", + "kind", + "laughing", + "loving", + "lucid", + "magical", + "mystifying", + "modest", + "musing", + "naughty", + "nervous", + "nice", + "nifty", + "nostalgic", + "objective", + "optimistic", + "peaceful", + "pedantic", + "pensive", + "practical", + "priceless", + "quirky", + "quizzical", + "recursing", + "relaxed", + "reverent", + "romantic", + "sad", + "serene", + "sharp", + "silly", + "sleepy", + "stoic", + "strange", + "stupefied", + "suspicious", + "sweet", + "tender", + "thirsty", + "trusting", + "unruffled", + "upbeat", + "vibrant", + "vigilant", + "vigorous", + "wizardly", + "wonderful", + "xenodochial", + "youthful", + "zealous", + "zen", + } - // Docker, starting from 0.7.x, generates names from notable scientists and hackers. - // Please, for any amazing man that you add to the list, consider adding an equally amazing woman to it, and vice versa. - right = [...]string{ - "aardvark", - "abyssinian", - "affenpinscher", - "akbash", - "akita", - "albatross", - "alligator", - "alpaca", - "angelfish", - "ant", - "anteater", - "antelope", - "ape", - "armadillo", - "ass", - "avocet", - "axolotl", - "baboon", - "badger", - "balinese", - "bandicoot", - "barb", - "barnacle", - "barracuda", - "bat", - "beagle", - "bear", - "beaver", - "bee", - "beetle", - "binturong", - "bird", - "birman", - "bison", - "bloodhound", - "boar", - "bobcat", - "bombay", - "bongo", - "bonobo", - "booby", - "budgerigar", - "buffalo", - "bulldog", - "bullfrog", - "burmese", - "butterfly", - "caiman", - "camel", - "capybara", - "caracal", - "caribou", - "cassowary", - "cat", - "caterpillar", - "catfish", - "cattle", - "centipede", - "chameleon", - "chamois", - "cheetah", - "chicken", - "chihuahua", - "chimpanzee", - "chinchilla", - "chinook", - "chipmunk", - "chough", - "cichlid", - "clam", - "coati", - "cobra", - "cockroach", - "cod", - "collie", - "coral", - "cormorant", - "cougar", - "cow", - "coyote", - "crab", - "crane", - "crocodile", - "crow", - "curlew", - "cuscus", - "cuttlefish", - "dachshund", - "dalmatian", - "deer", - "dhole", - "dingo", - "dinosaur", - "discus", - "dodo", - "dog", - "dogfish", - "dolphin", - "donkey", - "dormouse", - "dotterel", - "dove", - "dragonfly", - "drever", - "duck", - "dugong", - "dunker", - "dunlin", - "eagle", - "earwig", - "echidna", - "eel", - "eland", - "elephant", - "elk", - "emu", - "falcon", - "ferret", - "finch", - "fish", - "flamingo", - "flounder", - "fly", - "fossa", - "fox", - "frigatebird", - "frog", - "galago", - "gar", - "gaur", - "gazelle", - "gecko", - "gerbil", - "gharial", - "gibbon", - "giraffe", - "gnat", - "gnu", - "goat", - "goldfinch", - "goldfish", - "goose", - "gopher", - "gorilla", - "goshawk", - "grasshopper", - "greyhound", - "grouse", - "guanaco", - "gull", - "guppy", - "hamster", - "hare", - "harrier", - "havanese", - "hawk", - "hedgehog", - "heron", - "herring", - "himalayan", - "hippopotamus", - "hornet", - "horse", - "human", - "hummingbird", - "hyena", - "ibis", - "iguana", - "impala", - "indri", - "insect", - "jackal", - "jaguar", - "javanese", - "jay", - "jellyfish", - "kakapo", - "kangaroo", - "kingfisher", - "kiwi", - "koala", - "kouprey", - "kudu", - "labradoodle", - "ladybird", - "lapwing", - "lark", - "lemming", - "lemur", - "leopard", - "liger", - "lion", - "lionfish", - "lizard", - "llama", - "lobster", - "locust", - "loris", - "louse", - "lynx", - "lyrebird", - "macaw", - "magpie", - "mallard", - "maltese", - "manatee", - "mandrill", - "markhor", - "marten", - "mastiff", - "mayfly", - "meerkat", - "millipede", - "mink", - "mole", - "molly", - "mongoose", - "mongrel", - "monkey", - "moorhen", - "moose", - "mosquito", - "moth", - "mouse", - "mule", - "narwhal", - "neanderthal", - "newfoundland", - "newt", - "nightingale", - "numbat", - "ocelot", - "octopus", - "okapi", - "olm", - "opossum", - "orangutan", - "oryx", - "ostrich", - "otter", - "owl", - "ox", - "oyster", - "pademelon", - "panther", - "parrot", - "partridge", - "peacock", - "peafowl", - "pekingese", - "pelican", - "penguin", - "persian", - "pheasant", - "pig", - "pigeon", - "pika", - "pike", - "piranha", - "platypus", - "pointer", - "pony", - "poodle", - "porcupine", - "porpoise", - "possum", - "prawn", - "puffin", - "pug", - "puma", - "quail", - "quelea", - "quetzal", - "quokka", - "quoll", - "rabbit", - "raccoon", - "ragdoll", - "rail", - "ram", - "rat", - "rattlesnake", - "raven", - "reindeer", - "rhinoceros", - "robin", - "rook", - "rottweiler", - "ruff", - "salamander", - "salmon", - "sandpiper", - "saola", - "sardine", - "scorpion", - "seahorse", - "seal", - "serval", - "shark", - "sheep", - "shrew", - "shrimp", - "siamese", - "siberian", - "skunk", - "sloth", - "snail", - "snake", - "snowshoe", - "somali", - "sparrow", - "spider", - "sponge", - "squid", - "squirrel", - "starfish", - "starling", - "stingray", - "stinkbug", - "stoat", - "stork", - "swallow", - "swan", - "tang", - "tapir", - "tarsier", - "termite", - "tetra", - "tiffany", - "tiger", - "toad", - "tortoise", - "toucan", - "tropicbird", - "trout", - "tuatara", - "turkey", - "turtle", - "uakari", - "uguisu", - "umbrellabird", - "viper", - "vulture", - "wallaby", - "walrus", - "warthog", - "wasp", - "weasel", - "whale", - "whippet", - "wildebeest", - "wolf", - "wolverine", - "wombat", - "woodcock", - "woodlouse", - "woodpecker", - "worm", - "wrasse", - "wren", - "yak", - "zebra", - "zebu", - "zonkey", - "zorse", - } + // Docker, starting from 0.7.x, generates names from notable scientists and hackers. + // Please, for any amazing man that you add to the list, consider adding an equally amazing woman to it, and vice versa. + right = [...]string{ + "aardvark", + "abyssinian", + "affenpinscher", + "akbash", + "akita", + "albatross", + "alligator", + "alpaca", + "angelfish", + "ant", + "anteater", + "antelope", + "ape", + "armadillo", + "ass", + "avocet", + "axolotl", + "baboon", + "badger", + "balinese", + "bandicoot", + "barb", + "barnacle", + "barracuda", + "bat", + "beagle", + "bear", + "beaver", + "bee", + "beetle", + "binturong", + "bird", + "birman", + "bison", + "bloodhound", + "boar", + "bobcat", + "bombay", + "bongo", + "bonobo", + "booby", + "budgerigar", + "buffalo", + "bulldog", + "bullfrog", + "burmese", + "butterfly", + "caiman", + "camel", + "capybara", + "caracal", + "caribou", + "cassowary", + "cat", + "caterpillar", + "catfish", + "cattle", + "centipede", + "chameleon", + "chamois", + "cheetah", + "chicken", + "chihuahua", + "chimpanzee", + "chinchilla", + "chinook", + "chipmunk", + "chough", + "cichlid", + "clam", + "coati", + "cobra", + "cockroach", + "cod", + "collie", + "coral", + "cormorant", + "cougar", + "cow", + "coyote", + "crab", + "crane", + "crocodile", + "crow", + "curlew", + "cuscus", + "cuttlefish", + "dachshund", + "dalmatian", + "deer", + "dhole", + "dingo", + "dinosaur", + "discus", + "dodo", + "dog", + "dogfish", + "dolphin", + "donkey", + "dormouse", + "dotterel", + "dove", + "dragonfly", + "drever", + "duck", + "dugong", + "dunker", + "dunlin", + "eagle", + "earwig", + "echidna", + "eel", + "eland", + "elephant", + "elk", + "emu", + "falcon", + "ferret", + "finch", + "fish", + "flamingo", + "flounder", + "fly", + "fossa", + "fox", + "frigatebird", + "frog", + "galago", + "gar", + "gaur", + "gazelle", + "gecko", + "gerbil", + "gharial", + "gibbon", + "giraffe", + "gnat", + "gnu", + "goat", + "goldfinch", + "goldfish", + "goose", + "gopher", + "gorilla", + "goshawk", + "grasshopper", + "greyhound", + "grouse", + "guanaco", + "gull", + "guppy", + "hamster", + "hare", + "harrier", + "havanese", + "hawk", + "hedgehog", + "heron", + "herring", + "himalayan", + "hippopotamus", + "hornet", + "horse", + "human", + "hummingbird", + "hyena", + "ibis", + "iguana", + "impala", + "indri", + "insect", + "jackal", + "jaguar", + "javanese", + "jay", + "jellyfish", + "kakapo", + "kangaroo", + "kingfisher", + "kiwi", + "koala", + "kouprey", + "kudu", + "labradoodle", + "ladybird", + "lapwing", + "lark", + "lemming", + "lemur", + "leopard", + "liger", + "lion", + "lionfish", + "lizard", + "llama", + "lobster", + "locust", + "loris", + "louse", + "lynx", + "lyrebird", + "macaw", + "magpie", + "mallard", + "maltese", + "manatee", + "mandrill", + "markhor", + "marten", + "mastiff", + "mayfly", + "meerkat", + "millipede", + "mink", + "mole", + "molly", + "mongoose", + "mongrel", + "monkey", + "moorhen", + "moose", + "mosquito", + "moth", + "mouse", + "mule", + "narwhal", + "neanderthal", + "newfoundland", + "newt", + "nightingale", + "numbat", + "ocelot", + "octopus", + "okapi", + "olm", + "opossum", + "orangutan", + "oryx", + "ostrich", + "otter", + "owl", + "ox", + "oyster", + "pademelon", + "panther", + "parrot", + "partridge", + "peacock", + "peafowl", + "pekingese", + "pelican", + "penguin", + "persian", + "pheasant", + "pig", + "pigeon", + "pika", + "pike", + "piranha", + "platypus", + "pointer", + "pony", + "poodle", + "porcupine", + "porpoise", + "possum", + "prawn", + "puffin", + "pug", + "puma", + "quail", + "quelea", + "quetzal", + "quokka", + "quoll", + "rabbit", + "raccoon", + "ragdoll", + "rail", + "ram", + "rat", + "rattlesnake", + "raven", + "reindeer", + "rhinoceros", + "robin", + "rook", + "rottweiler", + "ruff", + "salamander", + "salmon", + "sandpiper", + "saola", + "sardine", + "scorpion", + "seahorse", + "seal", + "serval", + "shark", + "sheep", + "shrew", + "shrimp", + "siamese", + "siberian", + "skunk", + "sloth", + "snail", + "snake", + "snowshoe", + "somali", + "sparrow", + "spider", + "sponge", + "squid", + "squirrel", + "starfish", + "starling", + "stingray", + "stinkbug", + "stoat", + "stork", + "swallow", + "swan", + "tang", + "tapir", + "tarsier", + "termite", + "tetra", + "tiffany", + "tiger", + "toad", + "tortoise", + "toucan", + "tropicbird", + "trout", + "tuatara", + "turkey", + "turtle", + "uakari", + "uguisu", + "umbrellabird", + "viper", + "vulture", + "wallaby", + "walrus", + "warthog", + "wasp", + "weasel", + "whale", + "whippet", + "wildebeest", + "wolf", + "wolverine", + "wombat", + "woodcock", + "woodlouse", + "woodpecker", + "worm", + "wrasse", + "wren", + "yak", + "zebra", + "zebu", + "zonkey", + "zorse", + } ) func GetRandomName(retry int) string { - name := fmt.Sprintf("%s_%s_%s", left[rand.Intn(len(left))], left[rand.Intn(len(left))], right[rand.Intn(len(right))]) - if retry > 0 { - name = fmt.Sprintf("%s_%d", name, rand.Intn(10)) - } - return name + name := fmt.Sprintf("%s_%s_%s", left[rand.Intn(len(left))], left[rand.Intn(len(left))], right[rand.Intn(len(right))]) + if retry > 0 { + name = fmt.Sprintf("%s_%d", name, rand.Intn(10)) + } + return name } diff --git a/core/room.go b/core/room.go index 6573a0c..a639443 100644 --- a/core/room.go +++ b/core/room.go @@ -1,140 +1,139 @@ package core import ( - "encoding/json" - "fmt" - "github.com/gorilla/websocket" - "io/ioutil" - "laplace/config" - "os" + "encoding/json" + "fmt" + "github.com/Akilan1999/remotegameplay/config" + "github.com/gorilla/websocket" + "io/ioutil" + "os" ) type Room struct { - ID string `json:"id"` - Sessions map[string]*StreamSession - CallerConn *websocket.Conn - BarrierSession *Barrier + ID string `json:"id"` + Sessions map[string]*StreamSession + CallerConn *websocket.Conn + BarrierSession *Barrier } type StreamSession struct { - ID string - Offer string - Answer string - CallerIceCandidates []string - CalleeIceCandidates []string - CallerConn *websocket.Conn - CalleeConn *websocket.Conn + ID string + Offer string + Answer string + CallerIceCandidates []string + CalleeIceCandidates []string + CallerConn *websocket.Conn + CalleeConn *websocket.Conn } var roomMap = make(map[string]*Room) func GetRoom(id string) *Room { - return roomMap[id] + return roomMap[id] } func NewRoom(callerConn *websocket.Conn) *Room { - room := Room{ - ID: newRoomID(), - Sessions: make(map[string]*StreamSession), - CallerConn: callerConn, - } - roomMap[room.ID] = &room + room := Room{ + ID: newRoomID(), + Sessions: make(map[string]*StreamSession), + CallerConn: callerConn, + } + roomMap[room.ID] = &room - err := room.writeToFile() - if err != nil { - println(err) - } + err := room.writeToFile() + if err != nil { + println(err) + } - return &room + return &room } func newRoomID() string { - id := GetRandomName(0) - for GetRoom(id) != nil { - id = GetRandomName(0) - } - return id + id := GetRandomName(0) + for GetRoom(id) != nil { + id = GetRandomName(0) + } + return id } func RemoveRoom(id string) { - roomMap[id] = nil - // Writes nil to the file - roomMap[id].writeToFile() + roomMap[id] = nil + // Writes nil to the file + roomMap[id].writeToFile() } func (room *Room) GetSession(id string) *StreamSession { - return room.Sessions[id] + return room.Sessions[id] } func (room *Room) NewSession(calleeConn *websocket.Conn) *StreamSession { - session := StreamSession{ - ID: room.newSessionID(), - CallerIceCandidates: []string{}, - CalleeIceCandidates: []string{}, - CallerConn: room.CallerConn, - CalleeConn: calleeConn, - } + session := StreamSession{ + ID: room.newSessionID(), + CallerIceCandidates: []string{}, + CalleeIceCandidates: []string{}, + CallerConn: room.CallerConn, + CalleeConn: calleeConn, + } - room.Sessions[session.ID] = &session + room.Sessions[session.ID] = &session - return &session + return &session } func (room *Room) newSessionID() string { - id := fmt.Sprintf("%s$%s", room.ID, GetRandomName(0)) - for GetRoom(id) != nil { - id = fmt.Sprintf("%s$%s", room.ID, GetRandomName(0)) - } - return id + id := fmt.Sprintf("%s$%s", room.ID, GetRandomName(0)) + for GetRoom(id) != nil { + id = fmt.Sprintf("%s$%s", room.ID, GetRandomName(0)) + } + return id } // Write to rooms.json file -func (room *Room)writeToFile() error { - file, err := json.MarshalIndent(room, "", " ") - if err != nil { - return err - } +func (room *Room) writeToFile() error { + file, err := json.MarshalIndent(room, "", " ") + if err != nil { + return err + } - // Get Path from config - config, err := config.ConfigInit() - if err != nil { - return err - } + // Get Path from config + config, err := config.ConfigInit() + if err != nil { + return err + } - // Write room struct to json file - err = ioutil.WriteFile(config.Rooms, file, 0644) - if err != nil { - return err - } + // Write room struct to json file + err = ioutil.WriteFile(config.Rooms, file, 0644) + if err != nil { + return err + } - return nil + return nil } // ReadRoomsFile Reads rooms file and return struct room id func ReadRoomsFile() (*Room, error) { - config, err := config.ConfigInit() - if err != nil { - return nil,err - } - jsonFile, err := os.Open(config.Rooms) - // if we os.Open returns an error then handle it - if err != nil { - return nil,err - } + config, err := config.ConfigInit() + if err != nil { + return nil, err + } + jsonFile, err := os.Open(config.Rooms) + // if we os.Open returns an error then handle it + if err != nil { + return nil, err + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() - // defer the closing of our jsonFile so that we can parse it later on - defer jsonFile.Close() + // read our opened xmlFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) - // read our opened xmlFile as a byte array. - byteValue, _ := ioutil.ReadAll(jsonFile) + // we initialize our Users array + var rooms *Room - // we initialize our Users array - var rooms *Room + // we unmarshal our byteArray which contains our + // jsonFile's content into 'users' which we defined above + json.Unmarshal(byteValue, &rooms) - // we unmarshal our byteArray which contains our - // jsonFile's content into 'users' which we defined above - json.Unmarshal(byteValue, &rooms) - - return rooms, nil + return rooms, nil } diff --git a/core/signal.go b/core/signal.go index fb467ee..a7bf254 100644 --- a/core/signal.go +++ b/core/signal.go @@ -1,210 +1,210 @@ package core import ( - "fmt" - "github.com/gorilla/websocket" - "laplace/config" - "log" - "net/http" - "time" + "fmt" + "github.com/Akilan1999/remotegameplay/config" + "github.com/gorilla/websocket" + "log" + "net/http" + "time" ) type WSMessage struct { - SessionID string - Type string - Value string + SessionID string + Type string + Value string } var upgrader = websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, + ReadBufferSize: 1024, + WriteBufferSize: 1024, } func sendHeartBeatWS(ticker *time.Ticker, conn *websocket.Conn, quit chan struct{}) { - for { - select { - case <- ticker.C: - _ = conn.WriteJSON(WSMessage{ - Type: "beat", - }) - case <- quit: - log.Println("heartbeat stopped") - return - } - } + for { + select { + case <-ticker.C: + _ = conn.WriteJSON(WSMessage{ + Type: "beat", + }) + case <-quit: + log.Println("heartbeat stopped") + return + } + } } func GetHttp() *http.ServeMux { - server := http.NewServeMux() + server := http.NewServeMux() - server.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("files/static")))) + server.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("files/static")))) - server.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, "files/main.html") - }) + server.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "files/main.html") + }) - //Get hostname of the current machine - server.HandleFunc("/hostname", func(w http.ResponseWriter, r *http.Request) { + //Get hostname of the current machine + server.HandleFunc("/hostname", func(w http.ResponseWriter, r *http.Request) { - // Read hostname from config file - configResp, err := config.ConfigInit() - if err != nil { - print(err) - return - } + // Read hostname from config file + configResp, err := config.ConfigInit() + if err != nil { + print(err) + return + } - fmt.Fprintf(w, configResp.SystemUsername) - }) + fmt.Fprintf(w, configResp.SystemUsername) + }) - //Get SSH password of the current machine - server.HandleFunc("/SSHPassword", func(w http.ResponseWriter, r *http.Request) { + //Get SSH password of the current machine + server.HandleFunc("/SSHPassword", func(w http.ResponseWriter, r *http.Request) { - // Read hostname from config file - configResp, err := config.ConfigInit() - if err != nil { - print(err) - return - } + // Read hostname from config file + configResp, err := config.ConfigInit() + if err != nil { + print(err) + return + } - fmt.Fprintf(w, configResp.SSHPassword) - }) + fmt.Fprintf(w, configResp.SSHPassword) + }) - server.HandleFunc("/ws_serve", func(writer http.ResponseWriter, request *http.Request) { - conn, _ := upgrader.Upgrade(writer, request, nil) - room := NewRoom(conn) - if err := conn.WriteJSON(WSMessage{ - SessionID: "", - Type: "newRoom", - Value: room.ID, - }); err != nil { - log.Println("newSessionWriteJsonError.", err) - return - } + server.HandleFunc("/ws_serve", func(writer http.ResponseWriter, request *http.Request) { + conn, _ := upgrader.Upgrade(writer, request, nil) + room := NewRoom(conn) + if err := conn.WriteJSON(WSMessage{ + SessionID: "", + Type: "newRoom", + Value: room.ID, + }); err != nil { + log.Println("newSessionWriteJsonError.", err) + return + } - go func(r *Room) { - ticker := time.NewTicker(10 * time.Second) - quit := make(chan struct{}) - defer func() { - ticker.Stop() - _ = room.CallerConn.Close() - close(quit) - RemoveRoom(r.ID) + go func(r *Room) { + ticker := time.NewTicker(10 * time.Second) + quit := make(chan struct{}) + defer func() { + ticker.Stop() + _ = room.CallerConn.Close() + close(quit) + RemoveRoom(r.ID) - // Close the barrier session - if r.BarrierSession != nil { - r.BarrierSession.DeleteBarrierSession() - } + // Close the barrier session + if r.BarrierSession != nil { + r.BarrierSession.DeleteBarrierSession() + } - for sID, s := range r.Sessions { - _ = s.CalleeConn.WriteJSON(WSMessage{ - Type: "roomClosed", - SessionID: sID, - }) - } - }() + for sID, s := range r.Sessions { + _ = s.CalleeConn.WriteJSON(WSMessage{ + Type: "roomClosed", + SessionID: sID, + }) + } + }() - go sendHeartBeatWS(ticker, conn, quit) + go sendHeartBeatWS(ticker, conn, quit) - //noinspection ALL - defer room.CallerConn.Close() - for { - var msg WSMessage - if err := room.CallerConn.ReadJSON(&msg); err != nil { - log.Println("websocketError.", err) - return - } - //log.Println(msg) - s := room.GetSession(msg.SessionID) - if s == nil { - log.Println("session nil.", msg.SessionID) - } - if msg.Type == "addCallerIceCandidate" { - s.CallerIceCandidates = append(s.CallerIceCandidates, msg.Value) - } else if msg.Type == "gotOffer" { - s.Offer = msg.Value - } - if err := s.CalleeConn.WriteJSON(msg); err != nil { - log.Println("serveEchoWriteJsonError.", err) - } - } - }(room) - }) + //noinspection ALL + defer room.CallerConn.Close() + for { + var msg WSMessage + if err := room.CallerConn.ReadJSON(&msg); err != nil { + log.Println("websocketError.", err) + return + } + //log.Println(msg) + s := room.GetSession(msg.SessionID) + if s == nil { + log.Println("session nil.", msg.SessionID) + } + if msg.Type == "addCallerIceCandidate" { + s.CallerIceCandidates = append(s.CallerIceCandidates, msg.Value) + } else if msg.Type == "gotOffer" { + s.Offer = msg.Value + } + if err := s.CalleeConn.WriteJSON(msg); err != nil { + log.Println("serveEchoWriteJsonError.", err) + } + } + }(room) + }) - server.HandleFunc("/ws_connect", func(writer http.ResponseWriter, request *http.Request) { - conn, _ := upgrader.Upgrade(writer, request, nil) + server.HandleFunc("/ws_connect", func(writer http.ResponseWriter, request *http.Request) { + conn, _ := upgrader.Upgrade(writer, request, nil) - ids, ok := request.URL.Query()["id"] + ids, ok := request.URL.Query()["id"] - if !ok || ids[0] == "" { - return - } + if !ok || ids[0] == "" { + return + } - room := GetRoom(ids[0]) + room := GetRoom(ids[0]) - ip, ok := request.URL.Query()["barrierip"] + ip, ok := request.URL.Query()["barrierip"] - if ok && ip[0] != "" { - //Declaring struct - var barriersession Barrier - barriersession.IPAddress = ip[0] - room.BarrierSession = &barriersession - // Creates a barrier session - err := room.BarrierSession.CreateBarrierSession() - if err != nil { - return - } - } + if ok && ip[0] != "" { + //Declaring struct + var barriersession Barrier + barriersession.IPAddress = ip[0] + room.BarrierSession = &barriersession + // Creates a barrier session + err := room.BarrierSession.CreateBarrierSession() + if err != nil { + return + } + } - if room == nil { - _ = conn.WriteJSON(WSMessage{ - Type: "roomNotFound", - }) - return - } + if room == nil { + _ = conn.WriteJSON(WSMessage{ + Type: "roomNotFound", + }) + return + } - session := room.NewSession(conn) + session := room.NewSession(conn) - if err := room.CallerConn.WriteJSON(WSMessage{ - SessionID: session.ID, - Type: "newSession", - Value: session.ID, - }); err != nil { - log.Println("callerWriteJsonError.", err) - return - } + if err := room.CallerConn.WriteJSON(WSMessage{ + SessionID: session.ID, + Type: "newSession", + Value: session.ID, + }); err != nil { + log.Println("callerWriteJsonError.", err) + return + } - if err := conn.WriteJSON(WSMessage{ - SessionID: session.ID, - Type: "newSession", - Value: session.ID, - }); err != nil { - log.Println("calleeWriteJsonError.", err) - return - } + if err := conn.WriteJSON(WSMessage{ + SessionID: session.ID, + Type: "newSession", + Value: session.ID, + }); err != nil { + log.Println("calleeWriteJsonError.", err) + return + } - go func(s *StreamSession) { - //noinspection ALL - defer s.CalleeConn.Close() - for { - var msg WSMessage - if err := conn.ReadJSON(&msg); err != nil { - log.Println("websocketError.", err) - return - } - //log.Println(msg) - if msg.SessionID == s.ID { - if msg.Type == "addCalleeIceCandidate" { - s.CalleeIceCandidates = append(s.CalleeIceCandidates, msg.Value) - } else if msg.Type == "gotAnswer" { - s.Answer = msg.Value - } - if err := s.CallerConn.WriteJSON(msg); err != nil { - log.Println("connectEchoWriteJsonError.", err) - } - } - } - }(session) - }) + go func(s *StreamSession) { + //noinspection ALL + defer s.CalleeConn.Close() + for { + var msg WSMessage + if err := conn.ReadJSON(&msg); err != nil { + log.Println("websocketError.", err) + return + } + //log.Println(msg) + if msg.SessionID == s.ID { + if msg.Type == "addCalleeIceCandidate" { + s.CalleeIceCandidates = append(s.CalleeIceCandidates, msg.Value) + } else if msg.Type == "gotAnswer" { + s.Answer = msg.Value + } + if err := s.CallerConn.WriteJSON(msg); err != nil { + log.Println("connectEchoWriteJsonError.", err) + } + } + } + }(session) + }) - return server + return server } diff --git a/files/main.html b/files/main.html index 36c1daf..ef46788 100644 --- a/files/main.html +++ b/files/main.html @@ -3,19 +3,20 @@ - Laplace + RemoteGamePlay
+

based on the open source project Laplace

Laplace is an open-source project to enable screen sharing directly via browser. Made possible using WebRTC for low latency peer-to-peer connections, @@ -45,18 +46,18 @@

- - - - - - - - - - - - +

Connect to Barrier KVM (Beta)

+

+ This is a feature is still on beta testing. This feature will ensure that you can share the keyboard + and mouse of the server machine. +
+ Note: This only works if the laplace server has Barrierc installed and the room name you are connecting + too belongs to the server. +

+
Host Name: Not detected
+
+ +
@@ -181,8 +182,8 @@

diff --git a/go.mod b/go.mod index 7cf38e9..e4eb2cd 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module laplace +module github.com/Akilan1999/remotegameplay go 1.16 diff --git a/main.go b/main.go index 62ab6fb..47de9a1 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,8 @@ import ( "encoding/json" "flag" "fmt" - "laplace/config" - "laplace/core" + "github.com/Akilan1999/remotegameplay/config" + "github.com/Akilan1999/remotegameplay/core" "log" "math/rand" "net/http" @@ -15,6 +15,7 @@ import ( func main() { addr := flag.String("addr", "0.0.0.0:443", "Listen address") + port := flag.String("port", "8888", "port for running the server") tls := flag.Bool("tls", false, "Use TLS") setconfig := flag.Bool("setconfig", false, "Generates a config file") certFile := flag.String("certFile", "files/server.crt", "TLS cert file") @@ -23,7 +24,7 @@ func main() { roomInfo := flag.Bool("roomInfo", false, "Getting room id of headless server") killServer := flag.Bool("killServer", false, "Kills the laplace") killChromium := flag.Bool("killChromium", false, "Kills all chromuim") - BinaryToExcute := flag.String("BinaryToExecute","","Providing path (i.e Absolute path) of binary to execute") + BinaryToExcute := flag.String("BinaryToExecute", "", "Providing path (i.e Absolute path) of binary to execute") flag.Parse() @@ -47,7 +48,6 @@ func main() { return } - // Running in headless mode if *headless { Config, err := config.ConfigInit() @@ -75,7 +75,7 @@ func main() { } // Starting screen share headless - cmd := exec.Command("chromium-browser" ,"--no-sandbox","--auto-select-desktop-capture-source=Entire screen","--url","https://" + Addr + ":8888/?mode=headless","--ignore-certificate-errors") + cmd := exec.Command("chromium-browser", "--no-sandbox", "--auto-select-desktop-capture-source=Entire screen", "--url", "https://"+Addr+":"+*port+"/?mode=headless", "--ignore-certificate-errors") if err := cmd.Start(); err != nil { log.Fatalln(err) } @@ -96,22 +96,21 @@ func main() { // kills laplace server if *killServer { - cmd := exec.Command("pkill" ,"laplace") + cmd := exec.Command("pkill", "remotegameplay") if err := cmd.Run(); err != nil { fmt.Println(err) } return } - // kills chromium server + // kills chromium server if *killChromium { - cmd := exec.Command("pkill" ,"chromium") + cmd := exec.Command("pkill", "chromium") if err := cmd.Run(); err != nil { fmt.Println(err) } return } - if *tls { log.Println("Listening on TLS:", *addr) if err := http.ListenAndServeTLS(*addr, *certFile, *keyFile, server); err != nil { @@ -155,7 +154,7 @@ func Ip4or6(s string) string { func RunTask(task string) error { // Halts the process - cmd := exec.Command("sh",task) + cmd := exec.Command("sh", task) if err := cmd.Start(); err != nil { return err } diff --git a/run.sh b/run.sh index 217dcec..b729f7b 100644 --- a/run.sh +++ b/run.sh @@ -1,11 +1,11 @@ # Starts server and runs it silently (i.e no output in the terminal) -./laplace -tls -addr 0.0.0.0:8888 > /dev/null 2>&1 & +./remotegameplay -tls -addr 0.0.0.0:${2} > /dev/null 2>&1 & # Starts chromium browser and runs it silently (i.e no output in the terminal) -./laplace -headless -addr ${1} > /dev/null 2>&1 & +./remotegameplay -headless -addr ${1} -port ${2} > /dev/null 2>&1 & # Lets the script sleep for 2 seconds sleep 2 # Gets roomInfo and stores in the tmp directory as JSON -./laplace -headless -roomInfo > /tmp/output.txt +./remotegameplay -headless -roomInfo > /tmp/output.txt # Gets the room ID from the JSON file and outputs to tmp directory as text jq .id /tmp/output.txt > /tmp/test.txt # Gets roomID from tmp directory as text @@ -15,9 +15,9 @@ roomID=$(echo "$roomID" | tr -d '"') # Checks if the IP address is a IPV6 or IPV4 address if [ "$1" != "${1#*[0-9].[0-9]}" ]; then - echo "https://"${1}":8888/?roomID="${roomID} + echo "https://"${1}":${2}/?roomID="${roomID} elif [ "$1" != "${1#*:[0-9a-fA-F]}" ]; then - echo "https://["${1}"]:8888/?roomID="${roomID} + echo "https://["${1}"]:${2}/?roomID="${roomID} else echo "Unrecognized IP format '$1'" fi