package main
import (
"bufio"
"encoding/binary"
"fmt"
"image"
"image/png"
"os"
"sort"
"strconv"
"github.com/ethereum/go-ethereum/crypto"
)
var xs, ys, maxTime int
func set(pic *image.NRGBA, x, y, c, v int) {
if v > 255 {
v = 255
}
if x >= 0 && x < xs && y >= 0 && y < ys {
pic.Pix[y*pic.Stride+x*4+c] = uint8(v)
}
}
func main() {
var nodes uint64Slice
inputFile := "test.out"
if len(os.Args) > 1 {
inputFile = os.Args[1]
}
topic := "foo"
if len(os.Args) > 2 {
topic = os.Args[2]
}
topicHash := crypto.Keccak256Hash([]byte(topic))
fmt.Println(topicHash)
topicPrefix := binary.BigEndian.Uint64(topicHash[:8])
f, _ := os.Open(inputFile)
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
w := scanner.Text()
if w == "*N" {
scanner.Scan()
prefix, _ := strconv.ParseUint(scanner.Text(), 16, 64)
nodes = append(nodes, prefix^topicPrefix)
}
if w == "*R" {
scanner.Scan()
time, _ := strconv.ParseInt(scanner.Text(), 10, 64)
if int(time) > maxTime {
maxTime = int(time)
}
}
}
f.Close()
sort.Sort(nodes)
nodeIdx := make(map[uint64]int)
for i, v := range nodes {
nodeIdx[v^topicPrefix] = i
}
xs = maxTime / 10000
ys = len(nodes)
pic := image.NewNRGBA(image.Rect(0, 0, xs, ys))
for y := 0; y < ys; y++ {
for x := 0; x < xs; x++ {
set(pic, x, y, 3, 255)
}
}
pic2 := image.NewNRGBA(image.Rect(0, 0, xs, ys))
for y := 0; y < ys; y++ {
for x := 0; x < xs; x++ {
set(pic2, x, y, 3, 255)
}
}
f, _ = os.Open(inputFile)
scanner = bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
nodeRad := make(map[uint64]int)
for scanner.Scan() {
w := scanner.Text()
if w == "*R" {
scanner.Scan()
time, _ := strconv.ParseInt(scanner.Text(), 10, 64)
scanner.Scan()
if scanner.Text() == topic {
scanner.Scan()
prefix, _ := strconv.ParseUint(scanner.Text(), 16, 64)
scanner.Scan()
rad, _ := strconv.ParseInt(scanner.Text(), 10, 64)
if int(rad) != nodeRad[prefix] {
nodeRad[prefix] = int(rad)
radUint := uint64(rad) * ((^uint64(0)) / 1000000)
x := int(time * int64(xs) / int64(maxTime))
y := sort.Search(ys, func(i int) bool {
return nodes[i] > radUint
})
set(pic, x, y, 1, 255)
}
}
}
if w == "*MR" {
scanner.Scan()
time, _ := strconv.ParseInt(scanner.Text(), 10, 64)
scanner.Scan()
if scanner.Text() == topic {
scanner.Scan()
scanner.Scan()
rad, _ := strconv.ParseInt(scanner.Text(), 10, 64)
radUint := uint64(rad) * ((^uint64(0)) / 1000000)
x := int(time * int64(xs) / int64(maxTime))
y := sort.Search(ys, func(i int) bool {
return nodes[i] > radUint
})
set(pic, x, y, 0, 255)
}
}
if w == "*W" {
scanner.Scan()
time, _ := strconv.ParseInt(scanner.Text(), 10, 64)
scanner.Scan()
if scanner.Text() == topic {
scanner.Scan()
prefix, _ := strconv.ParseUint(scanner.Text(), 16, 64)
scanner.Scan()
wp, _ := strconv.ParseInt(scanner.Text(), 10, 64)
x := int(time * int64(xs) / int64(maxTime))
y := nodeIdx[prefix]
set(pic2, x, y, 0, int(wp/100000))
set(pic2, x, y, 1, int(wp/10000))
set(pic2, x, y, 2, int(wp/1000))
}
}
if w == "*+" {
scanner.Scan()
time, _ := strconv.ParseInt(scanner.Text(), 10, 64)
scanner.Scan()
if scanner.Text() == topic {
scanner.Scan()
prefix, _ := strconv.ParseUint(scanner.Text(), 16, 64)
x := int(time * int64(xs) / int64(maxTime))
y := nodeIdx[prefix]
set(pic, x, y, 2, 255)
scanner.Scan()
}
}
}
f.Close()
f, _ = os.Create("test.png")
w := bufio.NewWriter(f)
png.Encode(w, pic)
w.Flush()
f.Close()
f, _ = os.Create("test2.png")
w = bufio.NewWriter(f)
png.Encode(w, pic2)
w.Flush()
f.Close()
}
type uint64Slice []uint64
// Len is the number of elements in the collection.
func (s uint64Slice) Len() int {
return len(s)
}
// Less reports whether the element with
// index i should sort before the element with index j.
func (s uint64Slice) Less(i, j int) bool {
return s[i] < s[j]
}
// Swap swaps the elements with indexes i and j.
func (s uint64Slice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}