func DoTestLicense_Bl() { const ( email = "a@b" name = "nm" pass = "******" ) lic := license.Make(email) lic.Names = []string{name} lic.License = license.GenerateKey() lic.NewPassword(pass) if *verboseFlag > 0 { fmt.Printf("DoTestLicense load lic1 %#v\n", lic) } DoTestCheck("DoTestLicense VerifyPassword1", lic.VerifyPassword(pass, encryptionSalt)) saveSuccess := lic.Save_Bl() DoTestCheck("DoTestLicense Save", saveSuccess) lic2 := license.Load_Bl(email) if *verboseFlag > 0 { fmt.Printf("DoTestLicense load lic2 %#v\n", lic2) } DoTestCheck("DoTestLicense Load", lic2 != nil) if lic2 != nil { DoTestCheck("DoTestLicense VerifyPassword2", lic2.VerifyPassword(pass, encryptionSalt)) } }
// Helper function to create a user (license) and an avatar for that user func CreateUser(str string) { args := strings.Split(str, ",") if len(args) != 3 && len(args) != 4 { fmt.Println("Usage: server -createuser=email,password,avatar[,licensekey]") return } var up user up.New_WLwWLc(args[2]) up.Email = args[0] up.License, up.Password = license.Make(args[1], "") up.License = args[3] // Override c := ephenationdb.New().C("counters") var id struct { C uint32 } change := mgo.Change{ Update: bson.M{"$inc": bson.M{"c": 1}}, } _, err := c.FindId("avatarId").Apply(change, &id) if err != nil { fmt.Println("Failed to update unique counter 'avatarId' in collection 'counter'", err) return } up.Id = id.C db := ephenationdb.New() err = db.C("avatars").Insert(&up) if err != nil { log.Println("Save", up.Name, err) return } fmt.Println("Created avatar number", up.Id, ":", up.Name) }
// The player sent a string message func (up *user) playerStringMessage_RLuWLwRLqBlWLaWLc(buff []byte) { str := strings.TrimRight(string(buff), " ") // Remove trailing spaces, if any if *verboseFlag > 1 { log.Printf("User %v cmd: '%v'\n", up.pl.name, str) } message := strings.SplitN(str, " ", 2) switch message[0] { case "/keys": for _, key := range up.pl.Keys { up.Printf_Bl("!%s(%d), uid %d", key.Descr, key.Kid, key.Uid) } case "/activator": if len(message) < 2 { return } up.ActivatorControl(message[1]) case "/home": if len(message) == 1 { up.Lock() up.pl.coord = up.pl.homeSP up.updatedStats = true up.Unlock() } case "/sethome": cc := up.pl.coord.GetChunkCoord() cp := ChunkFind_WLwWLc(cc) if cp.owner != up.uid { up.Printf_Bl("#FAIL Not your territory") break } if len(message) == 1 { up.Lock() up.pl.homeSP = up.pl.coord up.Unlock() up.Printf_Bl("Home spawn point updated!") } case "/territory": if len(message) < 2 { return } up.TerritoryCommand_WLwWLcBl(strings.Split(message[1], " ")) case "/revive": if len(message) == 1 && up.pl.dead { up.Lock() up.pl.dead = false up.pl.hitPoints = 0.3 up.updatedStats = true up.pl.coord = up.pl.reviveSP up.Unlock() } case "/level": if (up.pl.adminLevel >= 8 || *allowTestUser) && len(message) == 2 { lvl, err := strconv.ParseUint(message[1], 10, 0) if err != nil { up.Printf_Bl("%s", err) } else { up.pl.level = uint32(lvl) up.updatedStats = true } } case "/timers": if up.pl.adminLevel >= 2 || *allowTestUser { timerstats.Report(up) } case "/panic": if up.pl.adminLevel >= 8 || *allowTestUser { log.Panic("client_prot.DEBUG command 'panic'") } case "/status": var m runtime.MemStats runtime.ReadMemStats(&m) up.Printf_Bl("!!Status") up.Printf_Bl("!Chunks loaded: %d, super chunks %d", worldCacheNumChunks, superChunkManager.Size()) up.Printf_Bl("!Num players:%v, monsters %v, near monsters %d", numPlayers, len(monsterData.m), CountNearMonsters_RLq(up.GetPreviousPos())) up.Printf_Bl("!Mem in use %vMB, total alloc %vMB, num malloc %vM, num free %vM", m.Alloc/1e6, m.TotalAlloc/1e6, m.Mallocs/1e6, m.Frees/1e6) up.Printf_Bl("!Worst message write %.6f s, Worst chunk read %.6f s", float64(WorstWriteTime)/float64(time.Second), float64(DBStats.WorstRead)/float64(time.Second)) up.Printf_Bl("!Num chunks read: %d, average read time %.6f", DBStats.NumRead, float64(DBStats.TotRead)/float64(DBStats.NumRead)/float64(time.Second)) up.Printf_Bl("!Created chunks: %d, average time %.6f", DBCreateStats.Num, float64(DBCreateStats.TotTime)/float64(DBCreateStats.Num)/float64(time.Second)) up.Printf_Bl("!%s", trafficStatistics) WorstWriteTime = 0 DBStats.WorstRead = 0 case "/players": up.ReportPlayers() case "/flying": up.pl.flying = !up.pl.flying up.pl.climbing = false // Always turn off climbing up.Printf_Bl("Flying: %v", up.pl.flying) case "/inv": fallthrough case "/inventory": if len(message) == 2 && up.pl.adminLevel > 8 { maker, ok := objectTable[message[1]] if message[1] == "clear" { up.pl.inventory.Clear() // There is no update message generated, so client won't know. up.pl.WeaponType = 0 up.pl.ArmorType = 0 up.pl.HelmetType = 0 up.pl.WeaponLvl = 0 up.pl.ArmorLvl = 0 up.pl.HelmetLvl = 0 } else if !ok { up.Printf_Bl("!Available objects:") for key, maker := range objectTable { up.Printf_Bl("!%v (%v)", maker(MonsterDifficulty(&up.pl.coord)), key) } } else { AddOneObjectToUser_WLuBl(up, maker(MonsterDifficulty(&up.pl.coord))) } } else { up.pl.inventory.Report(up) up.Printf_Bl("!Equip modifiers: armor %.0f%%, helmet %.0f%%, weapon %.0f%%", (ArmorLevelDiffMultiplier(up.pl.level, up.pl.ArmorLvl, up.pl.ArmorType)-1)*100, (ArmorLevelDiffMultiplier(up.pl.level, up.pl.HelmetLvl, up.pl.HelmetType)-1)*100, (WeaponLevelDiffMultiplier(up.pl.level, up.pl.WeaponLvl, up.pl.WeaponType)-1)*100) } case "/GC": var m runtime.MemStats runtime.ReadMemStats(&m) up.Printf_Bl("GC next: %v, num: %v, paus total: %v", m.NextGC, m.NumGC, m.PauseTotalNs) // runtime.GC() case "/shutdown": if up.pl.adminLevel >= 8 { if *cpuprofile != "" { pprof.StopCPUProfile() } GraceFulShutdown() // Will not return } case "/evalsync": for _, str := range evalsync.Eval() { up.Printf_Bl("!%s", str) } case "/resetpos": up.pl.coord.X = 0 up.pl.coord.Y = 0 up.pl.coord.Z = FLOATING_ISLANDS_LIM - PlayerHeight // As high as possible up.pl.flying = false up.pl.climbing = false case "/prof": if up.pl.adminLevel >= 8 || *allowTestUser { const fn = "profdata.tmp" f, _ := os.OpenFile(fn, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666) pprof.WriteHeapProfile(f) f.Close() up.Printf_Bl("pprof written to %s\n", fn) } case "/makelicense": if up.pl.adminLevel >= 8 && len(message) == 2 { args := strings.Split(message[1], " ") // split the rest of the input string into the arguments needed if len(args) != 3 { up.Printf_Bl("#FAIL Usage: /makelicense email password avatar") } else { email := args[0] oldlic := license.Load_Bl(email) if oldlic != nil { up.Printf_Bl("email %v already used (avatar %v)", email, oldlic.Names) } else { lic := license.Make(email) lic.NewPassword(args[1]) lic.License = license.GenerateKey() lic.Names = []string{args[2]} // Array of names, initialized with one entry ok := lic.Save_Bl() if ok { up.Printf_Bl("Saved %v", email) } else { up.Printf_Bl("#FAIL Failed to save %v", email) } } } } case "/loadlicense": if (up.pl.adminLevel >= 8 || *allowTestUser) && len(message) == 2 { email := message[1] lic := license.Load_Bl(email) up.Printf_Bl("%v", lic) } case "/say": if len(message) < 2 { break } near := playerQuadtree.FindNearObjects_RLq(up.GetPreviousPos(), client_prot.NEAR_OBJECTS) n := 0 for _, o := range near { other, ok := o.(*user) if !ok { continue // Only need to tell players, not monsters etc. } if other == up { continue // Found self } // Tell 'other' that we moved other.Printf("%s says: %s", up.pl.name, message[1]) n++ } if n == 0 { up.Printf_Bl("#FAIL No one is near") } else { up.Printf_Bl("You say: %s", message[1]) } case "/tell": if len(message) < 2 { break } up.TellOthers_RLaBl(message[1]) case "/friend": if len(message) < 2 { break } up.FriendCommand_RLaWLu(message[1]) case "/score": score.Report(up) case "/target": if len(message) < 2 { break } up.TargetCommand(message[1:]) } }