mirror of
https://github.com/blackboxprogramming/blackroad-apps.git
synced 2026-03-17 07:57:18 -05:00
📱 11 BlackRoad OS Apps
All published on BlackRoad OS App Store: - Dashboard, Metrics, Vault, Agent Hub - Commander, Analytics, Monitor - Deployer, Studio, Sync - Plus the original First App Zero gatekeepers. Zero fees.
This commit is contained in:
378
roadworld/main.go
Normal file
378
roadworld/main.go
Normal file
@@ -0,0 +1,378 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type World struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Type string `json:"type"`
|
||||
CreatedBy string `json:"created_by"`
|
||||
Players int `json:"players"`
|
||||
MaxPlayers int `json:"max_players"`
|
||||
IsPublic bool `json:"is_public"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
WorldID string `json:"world_id"`
|
||||
X float64 `json:"x"`
|
||||
Y float64 `json:"y"`
|
||||
Z float64 `json:"z"`
|
||||
Rotation float64 `json:"rotation"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
type GameObject struct {
|
||||
ID string `json:"id"`
|
||||
WorldID string `json:"world_id"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
X float64 `json:"x"`
|
||||
Y float64 `json:"y"`
|
||||
Z float64 `json:"z"`
|
||||
Scale float64 `json:"scale"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
var (
|
||||
worlds = make(map[string]*World)
|
||||
players = make(map[string]*Player)
|
||||
gameObjects = make(map[string]*GameObject)
|
||||
mu sync.RWMutex
|
||||
upgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool { return true },
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
worlds["earth-genesis"] = &World{
|
||||
ID: "earth-genesis",
|
||||
Name: "Earth - Beginning",
|
||||
Description: "Experience Earth from the very beginning",
|
||||
Type: "open-world",
|
||||
CreatedBy: "system",
|
||||
Players: 0,
|
||||
MaxPlayers: 1000,
|
||||
IsPublic: true,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
worlds["metaverse-hub"] = &World{
|
||||
ID: "metaverse-hub",
|
||||
Name: "Metaverse Hub",
|
||||
Description: "Central hub for virtual companies and games",
|
||||
Type: "hub",
|
||||
CreatedBy: "system",
|
||||
Players: 0,
|
||||
MaxPlayers: 5000,
|
||||
IsPublic: true,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
r.Use(func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
})
|
||||
|
||||
r.GET("/health", healthCheck)
|
||||
r.GET("/", root)
|
||||
|
||||
api := r.Group("/api")
|
||||
{
|
||||
api.GET("/worlds", getWorlds)
|
||||
api.GET("/worlds/:id", getWorld)
|
||||
api.POST("/worlds", createWorld)
|
||||
api.GET("/players", getPlayers)
|
||||
api.POST("/players", createPlayer)
|
||||
api.PUT("/players/:id", updatePlayer)
|
||||
api.GET("/objects", getGameObjects)
|
||||
api.POST("/objects", createGameObject)
|
||||
api.GET("/stats", getStats)
|
||||
}
|
||||
|
||||
r.GET("/ws", handleWebSocket)
|
||||
|
||||
log.Printf("🌍 RoadWorld running on port %s", port)
|
||||
log.Printf(" Health: http://localhost:%s/health", port)
|
||||
log.Printf(" API: http://localhost:%s/api", port)
|
||||
log.Printf(" WebSocket: ws://localhost:%s/ws", port)
|
||||
|
||||
if err := r.Run(":" + port); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func healthCheck(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"status": "healthy",
|
||||
"service": "RoadWorld API",
|
||||
"version": "1.0.0",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
"stats": gin.H{
|
||||
"total_worlds": len(worlds),
|
||||
"active_players": len(players),
|
||||
"total_objects": len(gameObjects),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func root(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"name": "RoadWorld",
|
||||
"description": "Metaverse & Game Creation Platform",
|
||||
"version": "1.0.0",
|
||||
"features": []string{
|
||||
"Open world Earth simulation",
|
||||
"Virtual company headquarters",
|
||||
"Game creation tools",
|
||||
"Real-time multiplayer",
|
||||
"WebGL rendering",
|
||||
"3D asset management",
|
||||
},
|
||||
"endpoints": gin.H{
|
||||
"worlds": "/api/worlds",
|
||||
"players": "/api/players",
|
||||
"objects": "/api/objects",
|
||||
"stats": "/api/stats",
|
||||
"ws": "/ws",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func getWorlds(c *gin.Context) {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
worldList := make([]*World, 0, len(worlds))
|
||||
for _, w := range worlds {
|
||||
worldList = append(worldList, w)
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"success": true,
|
||||
"count": len(worldList),
|
||||
"data": worldList,
|
||||
})
|
||||
}
|
||||
|
||||
func getWorld(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
mu.RLock()
|
||||
world, exists := worlds[id]
|
||||
mu.RUnlock()
|
||||
|
||||
if !exists {
|
||||
c.JSON(404, gin.H{"success": false, "error": "World not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"success": true, "data": world})
|
||||
}
|
||||
|
||||
func createWorld(c *gin.Context) {
|
||||
var world World
|
||||
if err := c.ShouldBindJSON(&world); err != nil {
|
||||
c.JSON(400, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
world.CreatedAt = time.Now()
|
||||
world.Players = 0
|
||||
|
||||
mu.Lock()
|
||||
worlds[world.ID] = &world
|
||||
mu.Unlock()
|
||||
|
||||
c.JSON(201, gin.H{"success": true, "data": world})
|
||||
}
|
||||
|
||||
func getPlayers(c *gin.Context) {
|
||||
worldID := c.Query("world_id")
|
||||
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
playerList := make([]*Player, 0)
|
||||
for _, p := range players {
|
||||
if worldID == "" || p.WorldID == worldID {
|
||||
playerList = append(playerList, p)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"success": true,
|
||||
"count": len(playerList),
|
||||
"data": playerList,
|
||||
})
|
||||
}
|
||||
|
||||
func createPlayer(c *gin.Context) {
|
||||
var player Player
|
||||
if err := c.ShouldBindJSON(&player); err != nil {
|
||||
c.JSON(400, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
players[player.ID] = &player
|
||||
if world, exists := worlds[player.WorldID]; exists {
|
||||
world.Players++
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
c.JSON(201, gin.H{"success": true, "data": player})
|
||||
}
|
||||
|
||||
func updatePlayer(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var updates Player
|
||||
if err := c.ShouldBindJSON(&updates); err != nil {
|
||||
c.JSON(400, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
if player, exists := players[id]; exists {
|
||||
player.X = updates.X
|
||||
player.Y = updates.Y
|
||||
player.Z = updates.Z
|
||||
player.Rotation = updates.Rotation
|
||||
mu.Unlock()
|
||||
c.JSON(200, gin.H{"success": true, "data": player})
|
||||
} else {
|
||||
mu.Unlock()
|
||||
c.JSON(404, gin.H{"success": false, "error": "Player not found"})
|
||||
}
|
||||
}
|
||||
|
||||
func getGameObjects(c *gin.Context) {
|
||||
worldID := c.Query("world_id")
|
||||
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
objectList := make([]*GameObject, 0)
|
||||
for _, obj := range gameObjects {
|
||||
if worldID == "" || obj.WorldID == worldID {
|
||||
objectList = append(objectList, obj)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"success": true,
|
||||
"count": len(objectList),
|
||||
"data": objectList,
|
||||
})
|
||||
}
|
||||
|
||||
func createGameObject(c *gin.Context) {
|
||||
var obj GameObject
|
||||
if err := c.ShouldBindJSON(&obj); err != nil {
|
||||
c.JSON(400, gin.H{"success": false, "error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
gameObjects[obj.ID] = &obj
|
||||
mu.Unlock()
|
||||
|
||||
c.JSON(201, gin.H{"success": true, "data": obj})
|
||||
}
|
||||
|
||||
func getStats(c *gin.Context) {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"success": true,
|
||||
"data": gin.H{
|
||||
"worlds": gin.H{
|
||||
"total": len(worlds),
|
||||
"public": countPublicWorlds(),
|
||||
"with_players": countWorldsWithPlayers(),
|
||||
},
|
||||
"players": gin.H{
|
||||
"total": len(players),
|
||||
"online": len(players),
|
||||
},
|
||||
"objects": gin.H{
|
||||
"total": len(gameObjects),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func countPublicWorlds() int {
|
||||
count := 0
|
||||
for _, w := range worlds {
|
||||
if w.IsPublic {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func countWorldsWithPlayers() int {
|
||||
count := 0
|
||||
for _, w := range worlds {
|
||||
if w.Players > 0 {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func handleWebSocket(c *gin.Context) {
|
||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
log.Println("WebSocket upgrade error:", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
log.Println("New WebSocket connection established")
|
||||
|
||||
for {
|
||||
messageType, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("WebSocket read error:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("Received: %s", message)
|
||||
|
||||
if err := conn.WriteMessage(messageType, message); err != nil {
|
||||
log.Println("WebSocket write error:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user