Skip to content

Commit 8c133b3

Browse files
authored
Merge pull request #346 from markus-wa/examples-use-radar-overviews.csgo.saiko.tech
examples: use radar-overviews.csgo.saiko.tech for radar images and offsets
2 parents a787e95 + bd3d1c0 commit 8c133b3

File tree

7 files changed

+110
-27
lines changed

7 files changed

+110
-27
lines changed

examples/README.md

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

33
Here you can find a overview of examples on how to use demoinfocs-golang.
44

5+
:information_source: Example code may not be production ready - specifically error handling and such is done in a simplified way and should not be used in critical systems as-is.
6+
57
|Example|Description
68
|-|-|
79
|[heatmap](heatmap)|Creating a heatmap from positions where players fired shots from|

examples/common.go

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
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+
13+
"github.com/golang/geo/r2"
14+
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/metadata"
815
)
916

1017
// DemoPathFromArgs returns the value of the -demo command line flag.
@@ -24,15 +31,20 @@ func DemoPathFromArgs() string {
2431
return demPath
2532
}
2633

34+
func checkError(err error) {
35+
if err != nil {
36+
panic(err)
37+
}
38+
}
39+
2740
// RedirectStdout redirects standard output to dev null.
2841
// Panics if an error occurs.
2942
func RedirectStdout(f func()) {
3043
// Redirect stdout, the resulting image is written to this
3144
old := os.Stdout
45+
3246
r, w, err := os.Pipe()
33-
if err != nil {
34-
panic(err)
35-
}
47+
checkError(err)
3648

3749
os.Stdout = w
3850

@@ -46,3 +58,57 @@ func RedirectStdout(f func()) {
4658

4759
os.Stdout = old
4860
}
61+
62+
type mapMetadata struct {
63+
PosX float64 `json:"pos_x,string"`
64+
PosY float64 `json:"pos_y,string"`
65+
Scale float64 `json:"scale,string"`
66+
}
67+
68+
// GetMapMetadata fetches metadata for a specific map version from
69+
// `https://radar-overviews.csgo.saiko.tech/<map>/<crc>/info.json`.
70+
// Panics if any error occurs.
71+
func GetMapMetadata(name string, crc uint32) metadata.Map {
72+
url := fmt.Sprintf("https://radar-overviews.csgo.saiko.tech/%s/%d/info.json", name, crc)
73+
74+
resp, err := http.Get(url)
75+
checkError(err)
76+
77+
defer resp.Body.Close()
78+
79+
var data map[string]mapMetadata
80+
81+
err = json.NewDecoder(resp.Body).Decode(&data)
82+
checkError(err)
83+
84+
mapInfo, ok := data[name]
85+
if !ok {
86+
panic(fmt.Sprintf("failed to get map info.json entry for %q", name))
87+
}
88+
89+
return metadata.Map{
90+
Name: name,
91+
PZero: r2.Point{
92+
X: mapInfo.PosX,
93+
Y: mapInfo.PosY,
94+
},
95+
Scale: mapInfo.Scale,
96+
}
97+
}
98+
99+
// GetMapMetadata fetches metadata for a specific map version from
100+
// `https://radar-overviews.csgo.saiko.tech/<map>/<crc>/info.json`.
101+
// Panics if any error occurs.
102+
func GetMapRadar(name string, crc uint32) image.Image {
103+
url := fmt.Sprintf("https://radar-overviews.csgo.saiko.tech/%s/%d/radar.png", name, crc)
104+
105+
resp, err := http.Get(url)
106+
checkError(err)
107+
108+
defer resp.Body.Close()
109+
110+
img, _, err := image.Decode(resp.Body)
111+
checkError(err)
112+
113+
return img
114+
}

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: 19 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,22 @@ 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 = ex.GetMapMetadata(header.MapName, msg.MapCrc)
52+
53+
// Load map overview image
54+
mapRadarImg = ex.GetMapRadar(header.MapName, msg.MapCrc)
55+
})
4556

4657
// Register handler for WeaponFire, triggered every time a shot is fired
4758
var points []r2.Point
59+
4860
p.RegisterEventHandler(func(e events.WeaponFire) {
4961
// Translate positions from in-game coordinates to radar overview image pixels
5062
x, y := mapMetadata.TranslateScale(e.Shooter.Position().X, e.Shooter.Position().Y)
@@ -69,7 +81,8 @@ func main() {
6981
}
7082

7183
// Transform r2.Points into heatmap.DataPoints
72-
var data []heatmap.DataPoint
84+
data := make([]heatmap.DataPoint, 0, len(points))
85+
7386
for _, p := range points[1:] {
7487
// Invert Y since go-heatmap expects data to be ordered from bottom to top
7588
data = append(data, heatmap.P(p.X, p.Y*-1))
@@ -79,15 +92,9 @@ func main() {
7992
// Drawing the image
8093
//
8194

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-
8895
// 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)
96+
img := image.NewRGBA(mapRadarImg.Bounds())
97+
draw.Draw(img, mapRadarImg.Bounds(), mapRadarImg, image.Point{}, draw.Over)
9198

9299
// Generate and draw heatmap overlay on top of the overview
93100
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: 15 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,17 @@ 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 = ex.GetMapMetadata(header.MapName, msg.MapCrc)
62+
63+
// Load map overview image
64+
mapRadarImg = ex.GetMapRadar(header.MapName, msg.MapCrc)
65+
})
5566

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

@@ -103,18 +114,11 @@ func main() {
103114
err = p.ParseToEnd()
104115
checkError(err)
105116

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-
113117
// Create output canvas
114-
dest := image.NewRGBA(imgMap.Bounds())
118+
dest := image.NewRGBA(mapRadarImg.Bounds())
115119

116120
// Draw image
117-
draw.Draw(dest, dest.Bounds(), imgMap, image.ZP, draw.Src)
121+
draw.Draw(dest, dest.Bounds(), mapRadarImg, image.Point{}, draw.Src)
118122

119123
// Initialize the graphic context
120124
gc := draw2dimg.NewGraphicContext(dest)

0 commit comments

Comments
 (0)