Skip to content

Commit 27bfbc0

Browse files
committed
examples: use radar-overviews.csgo.saiko.tech for radar images and offsets
1 parent a787e95 commit 27bfbc0

File tree

6 files changed

+116
-24
lines changed

6 files changed

+116
-24
lines changed

examples/common.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package examples
22

33
import (
4+
"encoding/json"
45
"flag"
6+
"fmt"
7+
"image"
58
"io"
69
"io/ioutil"
10+
"net/http"
711
"os"
12+
"strconv"
13+
14+
"github.com/golang/geo/r2"
15+
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/metadata"
816
)
917

1018
// DemoPathFromArgs returns the value of the -demo command line flag.
@@ -46,3 +54,68 @@ func RedirectStdout(f func()) {
4654

4755
os.Stdout = old
4856
}
57+
58+
func GetMapMetadata(name string, crc uint32) (metadata.Map, error) {
59+
url := fmt.Sprintf("https://radar-overviews.csgo.saiko.tech/%s/%d/info.json", name, crc)
60+
61+
resp, err := http.Get(url)
62+
if err != nil {
63+
return metadata.Map{}, fmt.Errorf("failed to get map info.json from %q: %v", url, err)
64+
}
65+
66+
defer resp.Body.Close()
67+
68+
var data map[string]interface{}
69+
70+
err = json.NewDecoder(resp.Body).Decode(&data)
71+
if err != nil {
72+
return metadata.Map{}, fmt.Errorf("failed to decode as JSON: %v", err)
73+
}
74+
75+
mapInfo, ok := data[name].(map[string]interface{})
76+
if !ok {
77+
return metadata.Map{}, fmt.Errorf("failed to get map info.json entry for %q", name)
78+
}
79+
80+
x, err := strconv.ParseFloat(mapInfo["pos_x"].(string), 64)
81+
if err != nil {
82+
return metadata.Map{}, fmt.Errorf("failed to get origin for X coordinate: %v", err)
83+
}
84+
85+
y, err := strconv.ParseFloat(mapInfo["pos_y"].(string), 64)
86+
if err != nil {
87+
return metadata.Map{}, fmt.Errorf("failed to get origin for Y coordinate: %v", err)
88+
}
89+
90+
scale, err := strconv.ParseFloat(mapInfo["scale"].(string), 64)
91+
if err != nil {
92+
return metadata.Map{}, fmt.Errorf("failed to get scale: %v", err)
93+
}
94+
95+
return metadata.Map{
96+
Name: name,
97+
PZero: r2.Point{
98+
X: x,
99+
Y: y,
100+
},
101+
Scale: scale,
102+
}, nil
103+
}
104+
105+
func GetMapRadar(name string, crc uint32) (image.Image, error) {
106+
url := fmt.Sprintf("https://radar-overviews.csgo.saiko.tech/%s/%d/radar.png", name, crc)
107+
108+
resp, err := http.Get(url)
109+
if err != nil {
110+
return nil, fmt.Errorf("failed to get map radar.png from %q: %v", url, err)
111+
}
112+
113+
defer resp.Body.Close()
114+
115+
img, _, err := image.Decode(resp.Body)
116+
if err != nil {
117+
return nil, fmt.Errorf("failed to decode as image: %v", err)
118+
}
119+
120+
return img, nil
121+
}

examples/heatmap/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This example shows how to create a heatmap from positions where players fired their weapons from.
44

5+
:information_source: Uses radar images from `https://radar-overviews.csgo.saiko.tech/<map>/<crc>/radar.png` - see https://github.com/saiko-tech/csgo-centrifuge for more info.
6+
57
See `heatmap.go` for the source code.
68

79
## Running the example

examples/heatmap/heatmap.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"fmt"
54
"image"
65
"image/draw"
76
"image/jpeg"
@@ -15,6 +14,7 @@ import (
1514
demoinfocs "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs"
1615
events "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/events"
1716
metadata "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/metadata"
17+
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/msg"
1818
)
1919

2020
const (
@@ -31,6 +31,7 @@ func main() {
3131

3232
f, err := os.Open(ex.DemoPathFromArgs())
3333
checkError(err)
34+
3435
defer f.Close()
3536

3637
p := demoinfocs.NewParser(f)
@@ -40,11 +41,24 @@ func main() {
4041
header, err := p.ParseHeader()
4142
checkError(err)
4243

43-
// Get metadata for the map that the game was played on for coordinate translations
44-
mapMetadata := metadata.MapNameToMap[header.MapName]
44+
var (
45+
mapMetadata metadata.Map
46+
mapRadarImg image.Image
47+
)
48+
49+
p.RegisterNetMessageHandler(func(msg *msg.CSVCMsg_ServerInfo) {
50+
// Get metadata for the map that the game was played on for coordinate translations
51+
mapMetadata, err = ex.GetMapMetadata(header.MapName, msg.MapCrc)
52+
checkError(err)
53+
54+
// Load map overview image
55+
mapRadarImg, err = ex.GetMapRadar(header.MapName, msg.MapCrc)
56+
checkError(err)
57+
})
4558

4659
// Register handler for WeaponFire, triggered every time a shot is fired
4760
var points []r2.Point
61+
4862
p.RegisterEventHandler(func(e events.WeaponFire) {
4963
// Translate positions from in-game coordinates to radar overview image pixels
5064
x, y := mapMetadata.TranslateScale(e.Shooter.Position().X, e.Shooter.Position().Y)
@@ -69,7 +83,8 @@ func main() {
6983
}
7084

7185
// Transform r2.Points into heatmap.DataPoints
72-
var data []heatmap.DataPoint
86+
data := make([]heatmap.DataPoint, 0, len(points))
87+
7388
for _, p := range points[1:] {
7489
// Invert Y since go-heatmap expects data to be ordered from bottom to top
7590
data = append(data, heatmap.P(p.X, p.Y*-1))
@@ -79,15 +94,9 @@ func main() {
7994
// Drawing the image
8095
//
8196

82-
// Load map overview image
83-
fMap, err := os.Open(fmt.Sprintf("../../assets/maps/%s.jpg", header.MapName))
84-
checkError(err)
85-
imgMap, _, err := image.Decode(fMap)
86-
checkError(err)
87-
8897
// Create output canvas and use map overview image as base
89-
img := image.NewRGBA(imgMap.Bounds())
90-
draw.Draw(img, imgMap.Bounds(), imgMap, image.Point{}, draw.Over)
98+
img := image.NewRGBA(mapRadarImg.Bounds())
99+
draw.Draw(img, mapRadarImg.Bounds(), mapRadarImg, image.Point{}, draw.Over)
91100

92101
// Generate and draw heatmap overlay on top of the overview
93102
imgHeatmap := heatmap.Heatmap(image.Rect(0, 0, bounds.Dx(), bounds.Dy()), data, dotSize, opacity, schemes.AlphaFire)

examples/heatmap/heatmap_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"os"
55
"testing"
6-
6+
77
"github.com/markus-wa/demoinfocs-golang/v2/examples"
88
)
99

examples/nade-trajectories/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This example shows how to create a overview of grenade trajectories of a match.
44

5+
:information_source: Uses radar images from `https://radar-overviews.csgo.saiko.tech/<map>/<crc>/radar.png` - see https://github.com/saiko-tech/csgo-centrifuge for more info.
6+
57
## Running the example
68

79
`go run nade_trajectories.go -demo /path/to/demo > out.jpg`

examples/nade-trajectories/nade_trajectories.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"image/color"
77
"image/draw"
88
"image/jpeg"
9-
_ "image/jpeg"
109
"os"
1110

1211
"github.com/golang/geo/r2"
@@ -18,6 +17,7 @@ import (
1817
common "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/common"
1918
events "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/events"
2019
metadata "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/metadata"
20+
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/msg"
2121
)
2222

2323
type nadePath struct {
@@ -43,6 +43,7 @@ var curMap metadata.Map
4343
func main() {
4444
f, err := os.Open(ex.DemoPathFromArgs())
4545
checkError(err)
46+
4647
defer f.Close()
4748

4849
p := demoinfocs.NewParser(f)
@@ -51,7 +52,19 @@ func main() {
5152
header, err := p.ParseHeader()
5253
checkError(err)
5354

54-
curMap = metadata.MapNameToMap[header.MapName]
55+
var (
56+
mapRadarImg image.Image
57+
)
58+
59+
p.RegisterNetMessageHandler(func(msg *msg.CSVCMsg_ServerInfo) {
60+
// Get metadata for the map that the game was played on for coordinate translations
61+
curMap, err = ex.GetMapMetadata(header.MapName, msg.MapCrc)
62+
checkError(err)
63+
64+
// Load map overview image
65+
mapRadarImg, err = ex.GetMapRadar(header.MapName, msg.MapCrc)
66+
checkError(err)
67+
})
5568

5669
nadeTrajectories := make(map[int64]*nadePath) // Trajectories of all destroyed nades
5770

@@ -103,18 +116,11 @@ func main() {
103116
err = p.ParseToEnd()
104117
checkError(err)
105118

106-
// Use map overview as base image
107-
fMap, err := os.Open(fmt.Sprintf("../../assets/maps/%s.jpg", header.MapName))
108-
checkError(err)
109-
110-
imgMap, _, err := image.Decode(fMap)
111-
checkError(err)
112-
113119
// Create output canvas
114-
dest := image.NewRGBA(imgMap.Bounds())
120+
dest := image.NewRGBA(mapRadarImg.Bounds())
115121

116122
// Draw image
117-
draw.Draw(dest, dest.Bounds(), imgMap, image.ZP, draw.Src)
123+
draw.Draw(dest, dest.Bounds(), mapRadarImg, image.Point{}, draw.Src)
118124

119125
// Initialize the graphic context
120126
gc := draw2dimg.NewGraphicContext(dest)

0 commit comments

Comments
 (0)