package main import ( "bytes" "flag" "fmt" "log" "net" "time" ) var ( host = flag.String("host", "127.0.0.1", "Server address (v4)") port = flag.String("port", "1337", "Server port") address string imagePath = flag.String("image", "foo.png", "Relative image path") imageOffsetX = flag.Int("xoffset", 0, "xoffset") imageOffsetY = flag.Int("yoffset", 0, "yoffset") canvasWidth = flag.Int("width", 1920, "canvas width") canvasHeight = flag.Int("height", 1080, "canvas height") testConn = flag.Bool("t", false, "test the connection before escalating completely") fill = flag.Bool("fill", true, "fill the complete canvas") color = flag.String("color", "000000", "define a color") cores = flag.Int("cores", 1, "Amount of cores to use") ) // parse the command line func parseFlags() { flag.Parse() address = fmt.Sprintf("%s:%s", *host, *port) } // test the connection to the given server if the -t flag was set func testConnection() { if *testConn == true { log.Printf("[ ] Testing Connection: True") log.Println("[ ] Testing TCP Connection...") testConnectionProtocol("tcp") } else { log.Printf("[ ] Testing Connection: False") } } // test connecting to the server using the given protocol ("udp" or "tcp") func testConnectionProtocol(protocol string) { connection, netDialErr := net.Dial(protocol, address) if netDialErr != nil { log.Fatal(netDialErr) } connectionCloseError := connection.Close() if connectionCloseError != nil { log.Fatal(connectionCloseError) } } func buildSendString(start int, end int, doneChannel chan bool, stripBufferChannel chan bytes.Buffer) { fmt.Printf("start: %d \t end: %d\n", start, end) var stripBuffer bytes.Buffer var currentCommand string for x := start; x < end; x++ { for y := 0; y < *canvasHeight; y++ { // prepare the command that should be written currentCommand = fmt.Sprintf("PX %d %d %s\n", x, y, *color) stripBuffer.Write([]byte(currentCommand)) } } doneChannel <- true stripBufferChannel <- stripBuffer } func main() { log.Printf("[ ] %s -> %s:%s at (%d, %d)", *imagePath, *host, *port, imageOffsetX, imageOffsetY) parseFlags() testConnection() doneChannel := make(chan bool) stripBufferChannel := make(chan bytes.Buffer) var completeBuffer bytes.Buffer var stripwidth int = *canvasWidth / *cores for thread := 0; thread < *cores; thread++ { log.Printf("Starting thread %d", thread) go buildSendString(thread * stripwidth, (thread + 1) * stripwidth, doneChannel, stripBufferChannel) } for thread := 0; thread < *cores; thread++ { log.Printf("Thread %d done!", thread) _ = <- doneChannel stripBufferChannelOutput := <- stripBufferChannel completeBuffer.Write(stripBufferChannelOutput.Bytes()) } // write connection, netDialError := net.Dial("tcp", address) if netDialError != nil { log.Fatal(netDialError) } _, writeErr := connection.Write(completeBuffer.Bytes()) if writeErr != nil { log.Fatal(writeErr) } connectionCloseError := connection.Close() if connectionCloseError != nil { log.Fatal(connectionCloseError) } // cleanup fmt.Printf("cleanup: %d -> %d", *cores * stripwidth, *canvasWidth) time.Sleep(1 * time.Second) }