Example #1
0
// Load loads a player .wrj data file. The passed account should be a hash
// returned by HashAccount. The name of the data file will be the account hash
// with .wrj appended to it.
//
// If an error is returned a nil *Player will always be returned.
//
// If the data file cannot be opened a BadCredentials error is returned - the
// account is incorrect if the file is not found.
//
// If the data file is opened but the password is incorrect a BadCredentials
// error is returned.
//
// If the data file cannot be unmarshaled a BadPlayerFile error is returned.
//
// NOTE: We are manually opening the player's file, reading it as a recordjar,
// peeking inside it, then unmarshaling it. This is so that we can abort at any
// point - player not found, incorrect password, corrupt player file - having
// done as little work as possible. In this way we are not unmarshaling players
// which may have a lot of dependant stuff (inventory) to unmarshal just to
// validate the login - someone could hit the server and tie up processing with
// invalid logins otherwise if the unmarshaling took a significant amount of
// time.
func Load(account string, password string) (*Player, error) {

	// Can we open the player's file to get the current salt and password hash?
	f, err := os.Open(config.DataDir + "players/" + account + ".wrj")
	if err != nil {
		return nil, BadCredentials
	}
	defer f.Close()

	rj, _ := recordjar.Read(f)

	d := recordjar.Decoder(rj[0])
	p := d.String("password")
	s := d.String("salt")

	// Password hash may be split over multiple lines in the data file which when
	// read will be concatenated together with spaces - which need removing.
	h := strings.Replace(p, " ", "", -1)

	if !PasswordValid(password, s, h) {
		return nil, BadCredentials
	}

	data := recordjar.UnmarshalJar(&rj)

	if data["PLAYER"] == nil {
		log.Printf("Error loading player: %#v", rj)
		return nil, BadPlayerFile
	}

	return data["PLAYER"].(*Player), nil
}
Example #2
0
func Save(e recordjar.Encoder) error {

	d := recordjar.Decoder(e)

	account := d.String("account")

	fileFlags := os.O_CREATE | os.O_EXCL | os.O_WRONLY

	f, err := os.OpenFile(config.DataDir+"players/"+account+".wrj", fileFlags, 0660)

	if err != nil {
		return err
	}
	defer f.Close()

	rj := recordjar.RecordJar{}
	rj = append(rj, recordjar.Record(e))
	recordjar.Write(f, rj)

	return nil
}
Example #3
0
// Read reads the config.wrj and sets new configuration values found in it.
//
// TODO: We should be able to reload and change settings at any time.
//
// TODO: Need to add more error checking of values coming in.
func Read() {

	ps := string(os.PathSeparator)

	for _, path := range searchPaths {
		log.Printf("Checking for %s in: %s", configName, path)
		if dir, err := os.Open(path + ps + configName); err != nil {
			if !os.IsNotExist(err) {
				log.Printf("Error checking for %s: %s", configName, err)
				continue
			}
		} else {
			defer dir.Close()
			log.Printf("Using: %s%s%s", path, ps, configName)
			rj, _ := recordjar.Read(dir)
			d := recordjar.Decoder(rj[0])

			ListenAddress = d.String("listen.address")
			ListenPort = d.String("listen.port")
			runtime.MemProfileRate = d.Int("mem.profile.rate")
			StatsRate = d.Duration("stats.rate")
			AccountIdMin = d.Int("account.id.min")
			AccountPasswordMin = d.Int("account.password.min")

			DataDir, _ = filepath.Abs(path + ps + d["data.dir"])
			DataDir += ps

			log.Printf("listen.address: %s", ListenAddress)
			log.Printf("listen.port: %s", ListenPort)
			log.Printf("mem.profile.rate: %d", MemProfileRate)
			log.Printf("stats.rate: %s", StatsRate)
			log.Printf("data.dir: %s", DataDir)
			log.Printf("account.id.min: %d", AccountIdMin)
			log.Printf("account.password.min: %d", AccountPasswordMin)

			break
		}
	}

}