Generate basic world & recieve data on client
This commit is contained in:
		@ -0,0 +1,3 @@
 | 
			
		||||
source_md5="ea3da320528c7d54640506628b12b80c"
 | 
			
		||||
dest_md5="f8c65d4e4cd80d79c48ff0c014cf0377"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								client/.import/dirt.png-2d96e51b4345f83ec0fb0c1ed8bf2b89.stex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								client/.import/dirt.png-2d96e51b4345f83ec0fb0c1ed8bf2b89.stex
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
source_md5="b38dac28f777cd24a94ae764cf60780a"
 | 
			
		||||
dest_md5="8568362e706ffbdddbdcb895eaad16c8"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								client/.import/grass.png-d6f949232ad65f7c5ac8611d6943aaf7.stex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								client/.import/grass.png-d6f949232ad65f7c5ac8611d6943aaf7.stex
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								client/art/tiles/dirt.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								client/art/tiles/dirt.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 108 B  | 
							
								
								
									
										34
									
								
								client/art/tiles/dirt.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								client/art/tiles/dirt.png.import
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
[remap]
 | 
			
		||||
 | 
			
		||||
importer="texture"
 | 
			
		||||
type="StreamTexture"
 | 
			
		||||
path="res://.import/dirt.png-2d96e51b4345f83ec0fb0c1ed8bf2b89.stex"
 | 
			
		||||
metadata={
 | 
			
		||||
"vram_texture": false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[deps]
 | 
			
		||||
 | 
			
		||||
source_file="res://art/tiles/dirt.png"
 | 
			
		||||
dest_files=[ "res://.import/dirt.png-2d96e51b4345f83ec0fb0c1ed8bf2b89.stex" ]
 | 
			
		||||
 | 
			
		||||
[params]
 | 
			
		||||
 | 
			
		||||
compress/mode=0
 | 
			
		||||
compress/lossy_quality=0.7
 | 
			
		||||
compress/hdr_mode=0
 | 
			
		||||
compress/bptc_ldr=0
 | 
			
		||||
compress/normal_map=0
 | 
			
		||||
flags/repeat=0
 | 
			
		||||
flags/filter=true
 | 
			
		||||
flags/mipmaps=false
 | 
			
		||||
flags/anisotropic=false
 | 
			
		||||
flags/srgb=2
 | 
			
		||||
process/fix_alpha_border=true
 | 
			
		||||
process/premult_alpha=false
 | 
			
		||||
process/HDR_as_SRGB=false
 | 
			
		||||
process/invert_color=false
 | 
			
		||||
stream=false
 | 
			
		||||
size_limit=0
 | 
			
		||||
detect_3d=true
 | 
			
		||||
svg/scale=1.0
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								client/art/tiles/grass.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								client/art/tiles/grass.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										34
									
								
								client/art/tiles/grass.png.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								client/art/tiles/grass.png.import
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
[remap]
 | 
			
		||||
 | 
			
		||||
importer="texture"
 | 
			
		||||
type="StreamTexture"
 | 
			
		||||
path="res://.import/grass.png-d6f949232ad65f7c5ac8611d6943aaf7.stex"
 | 
			
		||||
metadata={
 | 
			
		||||
"vram_texture": false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[deps]
 | 
			
		||||
 | 
			
		||||
source_file="res://art/tiles/grass.png"
 | 
			
		||||
dest_files=[ "res://.import/grass.png-d6f949232ad65f7c5ac8611d6943aaf7.stex" ]
 | 
			
		||||
 | 
			
		||||
[params]
 | 
			
		||||
 | 
			
		||||
compress/mode=0
 | 
			
		||||
compress/lossy_quality=0.7
 | 
			
		||||
compress/hdr_mode=0
 | 
			
		||||
compress/bptc_ldr=0
 | 
			
		||||
compress/normal_map=0
 | 
			
		||||
flags/repeat=0
 | 
			
		||||
flags/filter=false
 | 
			
		||||
flags/mipmaps=false
 | 
			
		||||
flags/anisotropic=false
 | 
			
		||||
flags/srgb=2
 | 
			
		||||
process/fix_alpha_border=true
 | 
			
		||||
process/premult_alpha=false
 | 
			
		||||
process/HDR_as_SRGB=false
 | 
			
		||||
process/invert_color=false
 | 
			
		||||
stream=false
 | 
			
		||||
size_limit=0
 | 
			
		||||
detect_3d=true
 | 
			
		||||
svg/scale=1.0
 | 
			
		||||
							
								
								
									
										43
									
								
								client/nodes/tileset.tres
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								client/nodes/tileset.tres
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
[gd_resource type="TileSet" load_steps=3 format=2]
 | 
			
		||||
 | 
			
		||||
[ext_resource path="res://art/tiles/grass.png" type="Texture" id=1]
 | 
			
		||||
[ext_resource path="res://art/tiles/dirt.png" type="Texture" id=2]
 | 
			
		||||
 | 
			
		||||
[resource]
 | 
			
		||||
0/name = "grass.png 0"
 | 
			
		||||
0/texture = ExtResource( 1 )
 | 
			
		||||
0/tex_offset = Vector2( 0, 0 )
 | 
			
		||||
0/modulate = Color( 1, 1, 1, 1 )
 | 
			
		||||
0/region = Rect2( 0, 0, 352, 160 )
 | 
			
		||||
0/tile_mode = 1
 | 
			
		||||
0/autotile/bitmask_mode = 1
 | 
			
		||||
0/autotile/bitmask_flags = [ Vector2( 0, 0 ), 432, Vector2( 0, 1 ), 438, Vector2( 0, 2 ), 54, Vector2( 0, 3 ), 48, Vector2( 1, 0 ), 504, Vector2( 1, 1 ), 511, Vector2( 1, 2 ), 63, Vector2( 1, 3 ), 56, Vector2( 2, 0 ), 216, Vector2( 2, 1 ), 219, Vector2( 2, 2 ), 27, Vector2( 2, 3 ), 24, Vector2( 3, 0 ), 144, Vector2( 3, 1 ), 146, Vector2( 3, 2 ), 18, Vector2( 3, 3 ), 16, Vector2( 4, 0 ), 176, Vector2( 4, 1 ), 182, Vector2( 4, 2 ), 434, Vector2( 4, 3 ), 50, Vector2( 4, 4 ), 178, Vector2( 5, 0 ), 248, Vector2( 5, 1 ), 255, Vector2( 5, 2 ), 507, Vector2( 5, 3 ), 59, Vector2( 5, 4 ), 251, Vector2( 6, 0 ), 440, Vector2( 6, 1 ), 447, Vector2( 6, 2 ), 510, Vector2( 6, 3 ), 62, Vector2( 6, 4 ), 446, Vector2( 7, 0 ), 152, Vector2( 7, 1 ), 155, Vector2( 7, 2 ), 218, Vector2( 7, 3 ), 26, Vector2( 7, 4 ), 154, Vector2( 8, 0 ), 184, Vector2( 8, 1 ), 191, Vector2( 8, 2 ), 506, Vector2( 8, 3 ), 58, Vector2( 8, 4 ), 186, Vector2( 9, 0 ), 443, Vector2( 9, 1 ), 254, Vector2( 9, 2 ), 442, Vector2( 9, 3 ), 190, Vector2( 10, 2 ), 250, Vector2( 10, 3 ), 187 ]
 | 
			
		||||
0/autotile/icon_coordinate = Vector2( 0, 0 )
 | 
			
		||||
0/autotile/tile_size = Vector2( 32, 32 )
 | 
			
		||||
0/autotile/spacing = 0
 | 
			
		||||
0/autotile/occluder_map = [  ]
 | 
			
		||||
0/autotile/navpoly_map = [  ]
 | 
			
		||||
0/autotile/priority_map = [  ]
 | 
			
		||||
0/autotile/z_index_map = [  ]
 | 
			
		||||
0/occluder_offset = Vector2( 0, 0 )
 | 
			
		||||
0/navigation_offset = Vector2( 0, 0 )
 | 
			
		||||
0/shape_offset = Vector2( 0, 0 )
 | 
			
		||||
0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
 | 
			
		||||
0/shape_one_way = false
 | 
			
		||||
0/shape_one_way_margin = 0.0
 | 
			
		||||
0/shapes = [  ]
 | 
			
		||||
0/z_index = 0
 | 
			
		||||
1/name = "dirt.png 1"
 | 
			
		||||
1/texture = ExtResource( 2 )
 | 
			
		||||
1/tex_offset = Vector2( 0, 0 )
 | 
			
		||||
1/modulate = Color( 1, 1, 1, 1 )
 | 
			
		||||
1/region = Rect2( 0, 0, 32, 32 )
 | 
			
		||||
1/tile_mode = 0
 | 
			
		||||
1/occluder_offset = Vector2( 0, 0 )
 | 
			
		||||
1/navigation_offset = Vector2( 0, 0 )
 | 
			
		||||
1/shape_offset = Vector2( 0, 0 )
 | 
			
		||||
1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
 | 
			
		||||
1/shape_one_way = false
 | 
			
		||||
1/shape_one_way_margin = 0.0
 | 
			
		||||
1/shapes = [  ]
 | 
			
		||||
1/z_index = 0
 | 
			
		||||
							
								
								
									
										11
									
								
								client/scenes/World.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								client/scenes/World.tscn
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -40,7 +40,7 @@ func login(_text=""):
 | 
			
		||||
			display_message(error.message)
 | 
			
		||||
		else:
 | 
			
		||||
			display_message("Connected to server!", Color.green)
 | 
			
		||||
			yield(ServerConnection.join_world_async(), "completed")
 | 
			
		||||
			# Load World
 | 
			
		||||
 | 
			
		||||
func display_message(message="", color=Color.red):
 | 
			
		||||
	errorLabel.add_color_override("font_color", color)
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
extends Node
 | 
			
		||||
 | 
			
		||||
signal tile_update(tile_data)
 | 
			
		||||
 | 
			
		||||
const KEY := "defaultkey"
 | 
			
		||||
const SERVER_ENDPOINT := "nakama.cloudsumu.com"
 | 
			
		||||
 | 
			
		||||
@ -8,6 +10,10 @@ var _client : NakamaClient = Nakama.create_client(KEY, SERVER_ENDPOINT, 7350, "h
 | 
			
		||||
var _socket : NakamaSocket
 | 
			
		||||
var _precenses : Dictionary = {}
 | 
			
		||||
 | 
			
		||||
enum OPCODE {
 | 
			
		||||
	tile_update = 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func authenticate_async(email : String, password : String) -> NakamaException:
 | 
			
		||||
	var result : NakamaException = null
 | 
			
		||||
	
 | 
			
		||||
@ -36,6 +42,7 @@ func connect_to_server_async() -> NakamaException:
 | 
			
		||||
	_socket = Nakama.create_socket_from(_client)
 | 
			
		||||
	var result : NakamaAsyncResult = yield(_socket.connect_async(_session), "completed")
 | 
			
		||||
	if not result.is_exception():
 | 
			
		||||
		_socket.connect("received_match_state", self, "_on_socket_received_match_state")
 | 
			
		||||
		_socket.connect("closed", self, "_on_socket_closed")
 | 
			
		||||
		return null
 | 
			
		||||
	return result.exception
 | 
			
		||||
@ -60,3 +67,9 @@ func join_world_async() -> Dictionary:
 | 
			
		||||
 | 
			
		||||
func _on_socket_closed():
 | 
			
		||||
	_socket = null
 | 
			
		||||
	
 | 
			
		||||
func _on_socket_received_match_state(match_state: NakamaRTAPI.MatchData):
 | 
			
		||||
	match match_state.op_code:
 | 
			
		||||
		OPCODE.tile_update:
 | 
			
		||||
			emit_signal("tile_update", JSON.parse(match_state.data).result)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								client/scripts/singletons/WorldManager.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								client/scripts/singletons/WorldManager.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
extends Node
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Declare member variables here. Examples:
 | 
			
		||||
# var a = 2
 | 
			
		||||
# var b = "text"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Called when the node enters the scene tree for the first time.
 | 
			
		||||
func _ready():
 | 
			
		||||
	ServerConnection.connect("tile_update", self, "on_tile_update")
 | 
			
		||||
	yield(ServerConnection.join_world_async(), "completed")
 | 
			
		||||
 | 
			
		||||
func on_tile_update(tile_data):
 | 
			
		||||
	print(tile_data)
 | 
			
		||||
@ -3,8 +3,14 @@ package control
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
 | 
			
		||||
	"github.com/heroiclabs/nakama-common/runtime"
 | 
			
		||||
	"github.com/josephbmanley/family/server/plugin/gamemap"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type OpCode int64
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	OpCodeTileUpdate = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Match struct{}
 | 
			
		||||
@ -12,20 +18,19 @@ type Match struct{}
 | 
			
		||||
type MatchState struct {
 | 
			
		||||
	presences map[string]runtime.Presence
 | 
			
		||||
	inputs    map[string]string
 | 
			
		||||
	positions map[string]string
 | 
			
		||||
	jumps     map[string]string
 | 
			
		||||
	colors    map[string]string
 | 
			
		||||
	positions map[string]map[string]int
 | 
			
		||||
	names     map[string]string
 | 
			
		||||
	worldMap  *gamemap.WorldMap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Match) MatchInit(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, params map[string]interface{}) (interface{}, int, string) {
 | 
			
		||||
 | 
			
		||||
	state := &MatchState{
 | 
			
		||||
		presences: map[string]runtime.Presence{},
 | 
			
		||||
		inputs:    map[string]string{},
 | 
			
		||||
		positions: map[string]string{},
 | 
			
		||||
		jumps:     map[string]string{},
 | 
			
		||||
		colors:    map[string]string{},
 | 
			
		||||
		positions: map[string]map[string]int{},
 | 
			
		||||
		names:     map[string]string{},
 | 
			
		||||
		worldMap:  gamemap.IntializeMap(),
 | 
			
		||||
	}
 | 
			
		||||
	tickRate := 10
 | 
			
		||||
	label := "{\"name\": \"Game World\"}"
 | 
			
		||||
@ -47,6 +52,20 @@ func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB
 | 
			
		||||
	mState, _ := state.(*MatchState)
 | 
			
		||||
	for _, precense := range presences {
 | 
			
		||||
		mState.presences[precense.GetUserId()] = precense
 | 
			
		||||
 | 
			
		||||
		mState.positions[precense.GetUserId()] = map[string]int{"x": 16, "y": 16}
 | 
			
		||||
 | 
			
		||||
		mState.names[precense.GetUserId()] = "User"
 | 
			
		||||
 | 
			
		||||
		if regionData, err := mState.worldMap.GetJsonRegion(16-8, 16+8, 16-8, 16+8); err != nil {
 | 
			
		||||
			logger.Error(err.Error())
 | 
			
		||||
			return mState
 | 
			
		||||
		} else {
 | 
			
		||||
			if sendErr := dispatcher.BroadcastMessage(OpCodeTileUpdate, regionData, []runtime.Presence{precense}, precense, true); sendErr != nil {
 | 
			
		||||
				logger.Error(sendErr.Error())
 | 
			
		||||
				return mState
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return mState
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								server/plugin/gamemap/gamemap.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								server/plugin/gamemap/gamemap.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
package gamemap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type WorldMap struct {
 | 
			
		||||
	data  [][]int
 | 
			
		||||
	max_x int
 | 
			
		||||
	max_y int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m WorldMap) GetTile(x int, y int) (int, error) {
 | 
			
		||||
	if x > m.max_x || y > m.max_y {
 | 
			
		||||
		return -1, fmt.Errorf("Map out of bounds error: %d, %d", x, y)
 | 
			
		||||
	}
 | 
			
		||||
	return m.data[x][y], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m WorldMap) GetJsonRegion(start_x, end_x, start_y, end_y int) ([]byte, error) {
 | 
			
		||||
	regionMap := make(map[int]map[int]int)
 | 
			
		||||
	for x := start_x; x < end_x; x++ {
 | 
			
		||||
 | 
			
		||||
		for y := start_y; y < end_y; y++ {
 | 
			
		||||
			if result, err := m.GetTile(x, y); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			} else {
 | 
			
		||||
				regionMap[x][y] = result
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	jsonString, err := json.Marshal(regionMap)
 | 
			
		||||
	return jsonString, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IntializeMap() *WorldMap {
 | 
			
		||||
	worldMap := new(WorldMap)
 | 
			
		||||
	worldMap.max_x = 64
 | 
			
		||||
	worldMap.max_y = 64
 | 
			
		||||
	for x := 0; x < worldMap.max_x; x++ {
 | 
			
		||||
		for y := 0; y < worldMap.max_y; y++ {
 | 
			
		||||
			worldMap.data[x][y] = 0
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add dot at top left for testing
 | 
			
		||||
	worldMap.data[0][0] = 1
 | 
			
		||||
 | 
			
		||||
	return worldMap
 | 
			
		||||
}
 | 
			
		||||
@ -15,6 +15,7 @@ github.com/heroiclabs/nakama-common v1.5.1 h1:ViCm9AvYYdQOCSKEa34SuSQ80JyZOHl6OD
 | 
			
		||||
github.com/heroiclabs/nakama-common v1.5.1/go.mod h1:nZAXHdeo4SyPlCyf7pU9rCVizxEhBF74gt7teDe/EaQ=
 | 
			
		||||
github.com/heroiclabs/nakama-common v1.7.2 h1:FQedePGCorBl3tXW4Ro8+XLGbEDQfGrT5Tb07j1UaLc=
 | 
			
		||||
github.com/josephbmanley/family v0.0.0-20200815220504-0d9d05943cef h1:6oijVkew6eKI1fGE+YMaxmiNlp/hkN9wDpStoid9/ZI=
 | 
			
		||||
github.com/josephbmanley/family v0.0.0-20200816202226-abfb0f428423 h1:ynsJFMYkfs3JspzvLCfmPGJwdKY/4QeX457U0+y4J1I=
 | 
			
		||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
			
		||||
@ -42,6 +43,7 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
 | 
			
		||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 | 
			
		||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 | 
			
		||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 | 
			
		||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
 | 
			
		||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 | 
			
		||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
			
		||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user