示例#1
0
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:])
	}
}