Skip to content

Commit

Permalink
Merge pull request #1 from XORbit01/complete-layout-functionality
Browse files Browse the repository at this point in the history
Complete layout functionality
  • Loading branch information
XORbit01 committed Apr 13, 2023
2 parents 64dd450 + 9007d82 commit 754388d
Show file tree
Hide file tree
Showing 16 changed files with 629 additions and 233 deletions.
97 changes: 79 additions & 18 deletions client/api.go
Expand Up @@ -5,8 +5,9 @@ type LeaderAPI struct {
}

type SoldierAPI struct {
Name string `json:"name"`
Ip string `json:"ip"`
Name string `json:"name"`
Ip string `json:"ip"`
Speed int `json:"speed"`
}

type CampSettings struct {
Expand All @@ -16,34 +17,94 @@ type CampSettings struct {
}

type CampAPI struct {
Leader LeaderAPI `json:"leader"`
Soldiers []SoldierAPI `json:"soldiers"`
Settings CampSettings `json:"camp_settings"`
Leader LeaderAPI `json:"leader"`
Soldiers []SoldierAPI `json:"soldiers"`
Settings CampSettings `json:"camp_settings"`
TotalSpeed int `json:"total_speed"`
}

func (camp CampAPI) Equals(c2 CampAPI) bool {
func compareMembers(first []SoldierAPI, second []SoldierAPI) ([]SoldierAPI, []SoldierAPI) {
firstMap := make(map[string]string)
secondMap := make(map[string]string)

// Count members in first slice
for _, member := range first {
firstMap[member.Ip] = member.Name
}

// Count members in second slice
for _, member := range second {
secondMap[member.Ip] = member.Name
}

added := make([]SoldierAPI, 0)
removed := make([]SoldierAPI, 0)

// Check for removed members
for ip, name := range firstMap {
if _, ok := secondMap[ip]; !ok {
removed = append(removed, SoldierAPI{Name: name, Ip: ip})
}
}

// Check for added members
for ip, name := range secondMap {
if _, ok := firstMap[ip]; !ok {
added = append(added, SoldierAPI{Name: name, Ip: ip})
}
}

return added, removed
}

func (camp CampAPI) Equals(c2 CampAPI) (yes bool, message string) {
message = ""
yes = true
if camp.TotalSpeed != c2.TotalSpeed {
yes = false
}
if camp.Leader.Name != c2.Leader.Name {
return false
yes = false
message += "leader changed: " + c2.Leader.Name + "\n"
}
if len(camp.Soldiers) != len(c2.Soldiers) {
return false
//check if speed changed
for _, soldier := range camp.Soldiers {
for _, soldier2 := range c2.Soldiers {
if soldier.Ip == soldier2.Ip && soldier.Name == soldier2.Name {
if soldier.Speed != soldier2.Speed {
yes = false
}
}
}
}
for i, soldier := range camp.Soldiers {
if soldier.Name != c2.Soldiers[i].Name {
return false
// check if set of soldiers is the same if not give me the difference
added, removed := compareMembers(c2.Soldiers, camp.Soldiers)
if len(added) > 0 {
yes = false
message += "soldier joined: "
for _, soldier := range added {
message += soldier.Name + "\n"
}
if soldier.Ip != c2.Soldiers[i].Ip {
return false
}
if len(removed) > 0 {
yes = false
message += "soldier left: "
for _, soldier := range removed {
message += soldier.Name + "\n"
}
}

if camp.Settings.Status != c2.Settings.Status {
return false
yes = false
message += "+" + camp.Settings.Status + "\n"
}
if camp.Settings.VictimServer != c2.Settings.VictimServer {
return false
yes = false
message += "victim changed: " + camp.Settings.VictimServer + "\n"
}
if camp.Settings.DDOSType != c2.Settings.DDOSType {
return false
yes = false
message += "ddos type changed: " + camp.Settings.DDOSType + "\n"
}
return true
return yes, message
}
174 changes: 44 additions & 130 deletions client/client.go
Expand Up @@ -8,26 +8,36 @@ import (
"github.com/fatih/color"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
)

type Leader struct {
Client
Password string
}

type Client struct {
http.Client `json:"-"`
Name string `json:"name"`
DispatcherServer string `json:"-"`
Speed int `json:"speed"`
}

func (c *Client) GetCamp() CampAPI {
//get request to dispatcher server /camp
func (c *Client) Ping() error {
rq, err := http.NewRequest("GET", c.DispatcherServer+"/ping", nil)
if err != nil {
return err
}
do, err := c.Do(rq)
if err != nil {
return err
}
if do.StatusCode == http.StatusOK {
return nil
}
return errors.New("error in pinging")
}

rq, err := http.NewRequest("GET", c.DispatcherServer+"/camp", nil)
func (c *Client) GetCamp() CampAPI {
rq, err := http.NewRequest("GET", c.DispatcherServer+"/camp?speed="+strconv.Itoa(c.Speed)+"&name="+c.Name, nil)
if err != nil {
return CampAPI{}
}
Expand Down Expand Up @@ -72,101 +82,48 @@ func (c *Client) JoinCamp() error {
return errors.New(msg)
}

func (l *Leader) RemoveFromCamp(password string) error {
//delete request to dispatcher server /camp/
//with body {name: c.Name}
rq, err := http.NewRequest("DELETE", l.DispatcherServer+"/camp", nil)
rq.Header.Add("Authorization", password)

if err != nil {
return err
}
do, err := l.Do(rq)
defer do.Body.Close()
if err != nil {
return err
}
if do.StatusCode == http.StatusOK {
return nil
} else {
//return the body as error message
var msg string
_ = json.NewDecoder(do.Body).Decode(&msg)
return errors.New(msg)
}
}

func (l *Leader) UpdateCampSettings(settings CampSettings) error {
//put request to dispatcher server /camp/
//convert settings to json and put it in the body
jr, err := json.Marshal(settings)
if err != nil {
return err
}

rq, err := http.NewRequest("PUT", l.DispatcherServer+"/camp", bytes.NewReader(jr))
if err != nil {
return err
}
rq.Header.Add("Authorization", l.Password)

do, err := l.Do(rq)
defer do.Body.Close()
if err != nil {
return err
}
if do.StatusCode == http.StatusOK {
return nil
} else {
var msg string
_ = json.NewDecoder(do.Body).Decode(&msg)
return errors.New(msg)
}
}

func (c *Client) ListenAndDo(ChangedDataChan chan CampAPI, logChan chan string) {
func (c *Client) ListenAndDo(changedDataChan chan CampAPI, logChan chan string) {
defer func() {
if r := recover(); r != nil {
//clear screen
fmt.Print("\033[H\033[2J")
color.Red("Dispatcher server is stopped")
os.Exit(0)
}
}()
prevCmp := c.GetCamp()
ChangedDataChan <- prevCmp
changedDataChan <- prevCmp
stopchan := make(chan bool, 1)
stopchan <- false

var cmp CampAPI
for {
cmp = c.GetCamp()
if !cmp.Equals(prevCmp) {
cmp := c.GetCamp()
if yes, message := cmp.Equals(prevCmp); !yes {
select {
case <-ChangedDataChan:
case <-changedDataChan:
default:
}
ChangedDataChan <- cmp
if cmp.Settings.DDOSType != prevCmp.Settings.DDOSType {
logChan <- "change attack mode " + cmp.Settings.DDOSType
}
if cmp.Settings.Status == "attacking" {
go StartAttack(cmp.Settings.VictimServer, cmp.Settings.DDOSType, stopchan, logChan)
}
if cmp.Settings.VictimServer != prevCmp.Settings.VictimServer {
logChan <- "Victim server changed to " + cmp.Settings.VictimServer
}

if cmp.Settings.Status == "stopped" {
select {
case <-stopchan:
default:
changedDataChan <- cmp
logChan <- message
if cmp.Settings.Status != prevCmp.Settings.Status {
if cmp.Settings.Status == "attacking" {
go c.StartAttack(cmp.Settings.VictimServer, cmp.Settings.DDOSType, stopchan, logChan)
}
if cmp.Settings.Status == "stopped" {
select {
case <-stopchan:
default:
}
stopchan <- true
}
stopchan <- true
}
prevCmp = cmp
time.Sleep(2 * time.Second)
}
time.Sleep(500 * time.Millisecond)
}
}

func (c *Client) Start() {
err := c.JoinCamp()
if err != nil {
//check if error contain connection refused
//if yes, then the dispatcher server is not running
if strings.Contains(err.Error(), "connection refused") {
color.Red("Dispatcher server is not running")
return
Expand All @@ -191,46 +148,3 @@ func (c *Client) Start() {
}()
wg.Wait()
}

func (l *Leader) ListenChangeView(changedDataChan chan CampAPI) {
prevCamp := l.GetCamp()
changedDataChan <- prevCamp
for {
camp := l.GetCamp()
if !camp.Equals(prevCamp) {
select {
case <-changedDataChan:
default:
}
changedDataChan <- camp
}
time.Sleep(1 * time.Second)
}
}
func (l *Leader) Start() {

func() {
defer func() {
if r := recover(); r != nil {
color.Red("Dispatcher server is not running")
os.Exit(0)
}
}()
l.GetCamp()
}()

var changedDataChan = make(chan CampAPI, 1)
logChan := make(chan string, 10)
wg := sync.WaitGroup{}
wg.Add(1)

go func() {
l.ListenChangeView(changedDataChan)
wg.Done()
}()
go func() {
l.StartLeaderView(changedDataChan, logChan)
wg.Done()
}()
wg.Wait()
}

0 comments on commit 754388d

Please sign in to comment.