Exemple #1
0
func reinitBlocks() {
	blockStateModels = map[pluginKey]*blockStateModel{}
	missingModel := findStateModel("steven", "missing_block")
	// Flatten the ids
	for _, bs := range blockSetsByID {
		if bs == nil {
			continue
		}
		for _, b := range bs.Blocks {
			br := reflect.ValueOf(b).Elem()
			// Liquids have custom rendering
			if _, ok := b.(*blockLiquid); ok || !b.Renderable() {
				continue
			}

			if model := findStateModel(b.Plugin(), b.ModelName()); model != nil {
				if variants := model.variant(b.ModelVariant()); variants != nil {
					br.FieldByName("BlockVariants").Set(
						reflect.ValueOf(variants),
					)
					continue
				}
				console.Text("Missing block variant (%s) for %s", b.ModelVariant(), b)
			} else {
				console.Text("Missing block model for %s", b)
			}
			br.FieldByName("BlockVariants").Set(
				reflect.ValueOf(missingModel.variant("normal")),
			)

		}
	}
}
Exemple #2
0
func initBlocks() {
	missingModel := findStateModel("steven", "missing_block")
	// Flatten the ids
	for _, bs := range blockSetsByID {
		if bs == nil {
			continue
		}
		for i, b := range bs.Blocks {
			br := reflect.ValueOf(b).Elem()
			br.FieldByName("Index").SetInt(int64(i))
			br.FieldByName("StevenID").SetUint(uint64(len(allBlocks)))
			allBlocks = append(allBlocks, b)
			if len(allBlocks) > math.MaxUint16 {
				panic("ran out of ids, time to do this correctly :(")
			}
			data := b.toData()
			if data != -1 {
				blocks[(bs.ID<<4)|data] = b
			}
			// Liquids have custom rendering
			if l, ok := b.(*blockLiquid); ok {
				if l.Lava {
					l.Tex = render.GetTexture("blocks/lava_still")
				} else {
					l.Tex = render.GetTexture("blocks/water_still")
				}
				continue
			}
			if !b.Renderable() {
				continue
			}

			if model := findStateModel(b.Plugin(), b.ModelName()); model != nil {
				if variants := model.variant(b.ModelVariant()); variants != nil {
					br.FieldByName("BlockVariants").Set(
						reflect.ValueOf(variants),
					)
					continue
				}
				if variants := model.matchPart(bs, b); variants != nil {
					br.FieldByName("BlockVariants").Set(
						reflect.ValueOf(variants),
					)
					continue
				}
				console.Text("Missing block variant (%s) for %s", b.ModelVariant(), b)
			} else {
				console.Text("Missing block model for %s", b)
			}
			br.FieldByName("BlockVariants").Set(
				reflect.ValueOf(missingModel.variant("normal")),
			)

		}
	}
}
Exemple #3
0
func parseBlockStateVariant(plugin string, js realjson.RawMessage) *model {
	type jsType struct {
		Model  string
		X, Y   float64
		UVLock bool
		Weight *int
	}
	var data jsType
	err := json.Unmarshal(js, &data)
	if err != nil {
		console.Text("%s", err)
		return nil
	}
	var bdata jsModel
	err = loadJSON(plugin, "models/block/"+data.Model+".json", &bdata)
	if err != nil {
		return nil
	}
	bm := parseModel(plugin, &bdata)

	bm.y = data.Y
	bm.x = data.X
	bm.uvLock = data.UVLock
	if data.Weight != nil {
		bm.weight = *data.Weight
	} else {
		bm.weight = 1
	}
	return bm
}
Exemple #4
0
func handleErrors() {
handle:
	for {
		select {
		case err := <-Client.network.Error():
			if !connected {
				continue
			}
			connected = false

			Client.network.Close()
			console.Text("Disconnected: %s", err)
			// Reset the ready state to stop packets from being
			// sent.
			ready = false
			if err != errManualDisconnect && disconnectReason.Value == nil {
				txt := &format.TextComponent{Text: err.Error()}
				txt.Color = format.Red
				disconnectReason.Value = txt
			}

			if Client.entity != nil && Client.entityAdded {
				Client.entityAdded = false
				Client.entities.container.RemoveEntity(Client.entity)
			}

			setScreen(newServerList())
		default:
			break handle
		}
	}
}
Exemple #5
0
func getAssetIndex() {
	console.Text("Getting asset index")
	defLocation := "./resources"
	resp, err := http.Get(fmt.Sprintf(assetIndexURL, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	if err := json.NewDecoder(resp.Body).Decode(&assets); err != nil {
		panic(err)
	}
	os.MkdirAll("./resources", 0777)
	f, err := os.Create(fmt.Sprintf("%s/%s.index", defLocation, assetsVersion))
	if err != nil {
		panic(err)
	}
	defer f.Close()
	json.NewEncoder(f).Encode(assets)
	console.Text("Got asset index for %s", assetsVersion)
}
Exemple #6
0
func parseModel(plugin string, data *jsModel) *model {
	var bm *model
	if data.Parent != "" && !strings.HasPrefix(data.Parent, "builtin/") {
		var pdata jsModel
		err := loadJSON(plugin, "models/"+data.Parent+".json", &pdata)
		if err != nil {
			console.Text("Error loading model %s: %s", data.Parent, err)
			loadJSON("steven", "models/block/missing_block.json", &pdata)
		}
		bm = parseModel(plugin, &pdata)
	} else {
		bm = &model{
			textureVars: map[string]string{},
			display:     map[string]modelDisplay{},
		}
		if strings.HasPrefix(data.Parent, "builtin/") {
			switch data.Parent {
			case "builtin/generated":
				bm.builtIn = builtInGenerated
			case "builtin/entity":
				bm.builtIn = builtInEntity
			case "builtin/compass":
				bm.builtIn = builtInCompass
			case "builtin/clock":
				bm.builtIn = builtInClock
			}
		}
	}

	if data.Textures != nil {
		for k, v := range data.Textures {
			bm.textureVars[k] = v
		}
	}

	for _, e := range data.Elements {
		bm.elements = append(bm.elements, parseBlockElement(e))
	}

	if data.AmbientOcclusion != nil {
		bm.ambientOcclusion = *data.AmbientOcclusion
		bm.aoSet = true
	} else if !bm.aoSet {
		bm.ambientOcclusion = true
	}

	if data.Display != nil {
		for k, v := range data.Display {
			bm.display[k] = v
		}
	}

	return bm
}
Exemple #7
0
func (h handler) handlePluginMessage(channel string, r io.Reader, serverbound bool) {
	var pm reflect.Type
	var ok bool
	if serverbound {
		pm, ok = pluginMessagesServerbound[channel]
	} else {
		pm, ok = pluginMessagesClientbound[channel]
	}
	if !ok {
		console.Text("Unhandled plugin message %s", channel)
		return
	}
	p := reflect.New(pm).Interface().(pluginMessage)
	err := p.read(r)
	if err != nil {
		console.Text("Failed to handle plugin message %s: %s", channel, err)
		return
	}
	h.Handle(p)
}
Exemple #8
0
func AddPack(path string) {
	console.Text("Adding pack " + path)
	if err := resource.LoadZip(path); err != nil {
		fmt.Println("Failed to load pack", path)
		return
	}
	if resourcePacks.Value() != "" {
		resourcePacks.SetValue(resourcePacks.Value() + "," + path)
	} else {
		resourcePacks.SetValue(path)
	}
	reloadResources()
}
Exemple #9
0
func loadStateModel(key pluginKey) *blockStateModel {
	type partCase struct {
		When  map[string]interface{}
		Apply realjson.RawMessage
	}
	type jsType struct {
		Variants  map[string]realjson.RawMessage
		Multipart []partCase
	}

	var data jsType
	err := loadJSON(key.Plugin, fmt.Sprintf("blockstates/%s.json", key.Name), &data)
	if err != nil {
		console.Text("Error loading state %s: %s", key.Name, err)
		return nil
	}
	bs := &blockStateModel{}
	if data.Variants != nil {
		bs.variants = map[string]*blockVariants{}
		for k, v := range data.Variants {
			bs.variants[k] = parseModelList(key, v)
		}
	}
	if data.Multipart != nil {
		for _, part := range data.Multipart {
			p := &blockPart{}
			bs.multipart = append(bs.multipart, p)
			if part.When == nil {
				p.When = func(bs *BlockSet, block Block) bool { return true }
			} else if or, ok := part.When["OR"].([]interface{}); ok {
				var checks []func(bs *BlockSet, block Block) bool
				for _, rules := range or {
					checks = append(checks, parseBlockRuleList(rules.(map[string]interface{})))
				}
				p.When = func(bs *BlockSet, block Block) bool {
					for _, rule := range checks {
						if rule(bs, block) {
							return true
						}
					}
					return false
				}
			} else {
				p.When = parseBlockRuleList(part.When)
			}
			p.Apply = parseModelList(key, part.Apply)
		}
	}
	return bs
}
Exemple #10
0
func loadBiomeColors(name string) *image.NRGBA {
	f, err := resource.Open("minecraft", fmt.Sprintf("textures/colormap/%s.png", name))
	if err != nil {
		console.Text("loading biome colors: %s", err)
		return image.NewNRGBA(image.Rect(0, 0, 256, 256))
	}
	defer f.Close()
	img, err := png.Decode(f)
	if err != nil {
		panic(err)
	}
	i, ok := img.(*image.NRGBA)
	if !ok {
		i = convertImage(img)
	}
	return i
}
Exemple #11
0
func RemovePack(path string) {
	console.Text("Removing pack " + path)
	resource.RemovePack(path)
	var buf bytes.Buffer
	for _, pck := range strings.Split(resourcePacks.Value(), ",") {
		if pck != path {
			buf.WriteString(pck)
			buf.WriteRune(',')
		}
	}
	val := buf.String()
	if strings.HasPrefix(val, ",") {
		val = val[:len(val)-1]
	}
	resourcePacks.SetValue(val)
	reloadResources()
}
Exemple #12
0
func loadFontInfo() {
	r, err := resource.Open("minecraft", "font/glyph_sizes.bin")
	if err != nil {
		console.Text("Error loading font info, %s", err)
		return
	}
	var data [0x10000]byte
	_, err = io.ReadFull(r, data[:])
	if err != nil {
		panic(err)
	}
	for i := range fontCharacterInfo {
		// Top nibble - start position
		// Bottom nibble - end position
		fontCharacterInfo[i].Start = int(data[i] >> 4)
		fontCharacterInfo[i].End = int(data[i]&0xF) + 1
	}
}
Exemple #13
0
func loadStateModel(key pluginKey) *blockStateModel {
	type jsType struct {
		Variants map[string]realjson.RawMessage
	}

	var data jsType
	err := loadJSON(key.Plugin, fmt.Sprintf("blockstates/%s.json", key.Name), &data)
	if err != nil {
		console.Text("Error loading state %s: %s", key.Name, err)
		return nil
	}
	bs := &blockStateModel{
		variants: map[string]blockVariants{},
	}
	variants := data.Variants
	for k, v := range variants {
		var models blockVariants
		switch v[0] {
		case '[':
			var list []realjson.RawMessage
			json.Unmarshal(v, &list)
			for _, vv := range list {
				mdl := parseBlockStateVariant(key.Plugin, vv)
				if mdl != nil {
					models = append(models, precomputeModel(mdl))
				}
			}
		default:
			mdl := parseBlockStateVariant(key.Plugin, v)
			if mdl != nil {
				models = append(models, precomputeModel(mdl))
			}
		}
		bs.variants[k] = models
	}
	return bs
}
Exemple #14
0
func reloadResources() {
	console.Text("Bringing everything to a stop")
	for freeBuilders < maxBuilders {
		select {
		case pos := <-completeBuilders:
			freeBuilders++
			if c := chunkMap[chunkPosition{pos.X, pos.Z}]; c != nil {
				if s := c.Sections[pos.Y]; s != nil {
					s.building = false
				}
			}
		}
	}
	locale.Clear()
	render.LoadSkinBuffer()
	modelCache = map[string]*model{}
	console.Text("Reloading textures")
	render.LoadTextures()
	console.Text("Reloading biomes")
	loadBiomes()
	ui.ForceDraw()
	console.Text("Reloading blocks")
	reinitBlocks()
	console.Text("Marking chunks for rebuild")
	for _, c := range chunkMap {
		for _, s := range c.Sections {
			if s != nil {
				s.dirty = true
			}
		}
	}
	console.Text("Rebuilding static models")
	render.RefreshModels()
	console.Text("Reloading inventory")
	Client.playerInventory.Update()
}
Exemple #15
0
func (handler) ServerMessage(msg *protocol.ServerMessage) {
	console.Text("MSG(%d): %s", msg.Type, msg.Message.Value)
	Client.chat.Add(msg.Message)
}
Exemple #16
0
func (handler) Disconnect(d *protocol.Disconnect) {
	disconnectReason = d.Reason
	console.Text("Disconnect: %s", disconnectReason)
	Client.network.SignalClose(errManualDisconnect)
}
Exemple #17
0
func (f Framebuffer) Check() {
	console.Text("%04X", gl.CheckFramebufferStatus(gl.FRAMEBUFFER))
}
Exemple #18
0
func (n *networkManager) Connect(profile mojang.Profile, server string) {
	logLevel := networkLog.Value()
	go func() {
		var err error
		n.conn, err = protocol.Dial(server)
		if err != nil {
			n.SignalClose(err)
			return
		}
		if logLevel > 0 {
			n.conn.Logger = func(read bool, packet protocol.Packet) {
				if !read && logLevel < 2 {
					return
				}
				if logLevel < 3 {
					switch packet.(type) {
					case *protocol.ChunkData:
						return
					}
				}
				dir := "read"
				if !read {
					dir = "write"
				}
				console.Text("%s[%s] %T%+v", server, dir, packet, packet)
			}
		}

		err = n.conn.LoginToServer(profile)
		if err != nil {
			n.SignalClose(err)
			return
		}

	preLogin:
		for {
			packet, err := n.conn.ReadPacket()
			if err != nil {
				n.SignalClose(err)
				return
			}
			switch packet := packet.(type) {
			case *protocol.SetInitialCompression:
				n.conn.SetCompression(int(packet.Threshold))
			case *protocol.LoginSuccess:
				n.conn.State = protocol.Play
				break preLogin
			case *protocol.LoginDisconnect:
				n.SignalClose(errors.New(packet.Reason.String()))
				return
			default:
				n.SignalClose(fmt.Errorf("unhandled packet %T", packet))
				return
			}
		}

		first := true
		for {
			packet, err := n.conn.ReadPacket()
			if err != nil {
				n.SignalClose(err)
				return
			}
			if first {
				go n.writeHandler()
				first = false
			}

			// Handle keep alives async as there is no need to process them
			switch packet := packet.(type) {
			case *protocol.KeepAliveClientbound:
				n.Write(&protocol.KeepAliveServerbound{ID: packet.ID})
			case *protocol.SetCompression:
				n.conn.SetCompression(int(packet.Threshold))
			default:
				n.readChan <- packet
			}
		}
	}()
}
Exemple #19
0
func downloadAssets() {
	defLocation := "./resources"
	total := newProgressBar()
	var totalSize, totalCount int64
	for _, v := range assets.Objects {
		totalSize += int64(v.Size)
	}
	limiter := make(chan struct{}, 4)
	for i := 0; i < 4; i++ {
		limiter <- struct{}{}
	}
	go func() {
		var wg sync.WaitGroup
		for file, v := range assets.Objects {
			v := v
			file := file
			path := hashPath(v.Hash)
			loc := fmt.Sprintf("%s/%s", defLocation, path)
			_, err := os.Stat(loc)
			if !os.IsNotExist(err) {
				continue
			}
			<-limiter
			wg.Add(1)
			go func() {
				defer wg.Done()
				var prog *progressBar
				wait := make(chan struct{})
				syncChan <- func() { prog = newProgressBar(); wait <- struct{}{} }
				<-wait
				func() {
					resp, err := http.Get(fmt.Sprintf(assetResourceURL, path))
					if err != nil {
						panic(err)
					}
					defer resp.Body.Close()
					os.MkdirAll(filepath.Dir(loc), 0777)
					f, err := os.Create(loc + ".tmp")
					if err != nil {
						panic(err)
					}
					defer f.Close()
					n, err := prog.watchCopy(f, resp.Body, resp.ContentLength, fmt.Sprintf("Downloading %s: %%v/100", file))
					if err != nil {
						panic(err)
					}
					if n != int64(v.Size) {
						panic(fmt.Sprintf("Got: %d, Wanted: %d for %s", n, v.Size, fmt.Sprintf(assetResourceURL, path)))
					}
					console.Text("Downloaded: %s", loc)
				}()
				os.Rename(loc+".tmp", loc)
				syncChan <- func() {
					prog.remove()
					totalCount += int64(v.Size)
					progress := float64(totalCount) / float64(totalSize)
					total.update(progress, fmt.Sprintf("Downloading assets: %v/100", int(100*progress)))
				}
				limiter <- struct{}{}
			}()
		}
		wg.Wait()
		syncChan <- func() {
			total.remove()
			loadSoundData()
		}
	}()
}
Exemple #20
0
func downloadDefault(tick TickFunc, sync chan<- func(), target string) {
	console.Text("Obtaining vanilla resources for %s, please wait...", ResourcesVersion)
	resp, err := http.Get(fmt.Sprintf(vanillaURL, ResourcesVersion))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	os.MkdirAll("./", 0777)
	f, err := os.Create(target + ".tmp")
	if err != nil {
		panic(err)
	}
	defer os.Remove(target + ".tmp")
	defer f.Close()
	_, err = io.Copy(f, &progressRead{
		max:  resp.ContentLength,
		tick: tick,
		sync: sync,
		r:    resp.Body,
	})
	if err != nil {
		panic(err)
	}

	f.Seek(0, 0) // Go back to the start
	fr, err := zip.NewReader(f, resp.ContentLength)
	if err != nil {
		panic(err)
	}

	os.MkdirAll(target, 0777)

	// Copy the assets (not the classes) in the new zip
	fCount := float64(len(fr.File))
	for i, f := range fr.File {
		if !strings.HasPrefix(f.Name, "assets/") {
			continue
		}
		func() {
			path := filepath.Join(target, f.Name)
			os.MkdirAll(filepath.Dir(path), 0777)
			w, err := os.Create(path)
			if err != nil {
				panic(err)
			}
			defer w.Close()
			r, err := f.Open()
			if err != nil {
				panic(err)
			}
			defer r.Close()
			_, err = io.Copy(w, r)
			if err != nil {
				panic(err)
			}
		}()
		sync <- func() {
			tick(0.75+(float64(i)/fCount)*0.25, false)
		}
	}
	lFile, err := os.Create(fmt.Sprintf("%s/steven.assets", target))
	if err != nil {
		panic(err)
	}
	defer lFile.Close()
	lFile.WriteString(ResourcesVersion)
}
Exemple #21
0
// DebugLog enables OpenGL's debug messages and logs them to stdout.
func DebugLog() {
	gl.DebugMessageCallback(func(
		source uint32,
		gltype uint32,
		id uint32,
		severity uint32,
		length int32,
		message string,
		userParam unsafe.Pointer) {
		// Source
		strSource := "unknown"
		switch source {
		case gl.DEBUG_SOURCE_API:
			strSource = "api"
		case gl.DEBUG_SOURCE_WINDOW_SYSTEM:
			strSource = "windowSystem"
		case gl.DEBUG_SOURCE_SHADER_COMPILER:
			strSource = "shaderCompiler"
		case gl.DEBUG_SOURCE_THIRD_PARTY:
			strSource = "thirdParty"
		case gl.DEBUG_SOURCE_APPLICATION:
			strSource = "application"
		case gl.DEBUG_SOURCE_OTHER:
			strSource = "other"
		}
		// Type
		strType := "unknown"
		switch gltype {
		case gl.DEBUG_TYPE_ERROR:
			strType = "error"
		case gl.DEBUG_TYPE_DEPRECATED_BEHAVIOR:
			strType = "deprecatedBehavior"
		case gl.DEBUG_TYPE_UNDEFINED_BEHAVIOR:
			strType = "undefinedBehavior"
		case gl.DEBUG_TYPE_PORTABILITY:
			strType = "portability"
		case gl.DEBUG_TYPE_PERFORMANCE:
			strType = "performance"
		case gl.DEBUG_TYPE_MARKER:
			strType = "marker"
		case gl.DEBUG_TYPE_PUSH_GROUP:
			strType = "pushGroup"
		case gl.DEBUG_TYPE_POP_GROUP:
			strType = "popGroup"
		case gl.DEBUG_TYPE_OTHER:
			strType = "other"
		}
		// Severity
		strSeverity := "unknown"
		switch severity {
		case gl.DEBUG_SEVERITY_HIGH:
			strSeverity = "high"
		case gl.DEBUG_SEVERITY_MEDIUM:
			strSeverity = "medium"
		case gl.DEBUG_SEVERITY_LOW:
			strSeverity = "low"
		case gl.DEBUG_SEVERITY_NOTIFICATION:
			return
		}
		console.Text("[%s][%s][%s]: %s", strSource, strType, strSeverity, message)
	}, nil)
}
Exemple #22
0
func playSoundInternal(cat soundCategory, snd sound, vol, pitch float64, rel bool, pos mgl32.Vec3, cb func()) {
	vol *= snd.Volume * 100
	baseVol := vol
	vol *= float64(muVolMaster.Value()) / 100
	if v, ok := volVars[cat]; ok {
		vol *= float64(v.Value()) / 100
	}
	if vol <= 0 {
		if cb != nil {
			go func() { syncChan <- cb }()
		}
		return
	}
	name := snd.Name
	key := pluginKey{"minecraft", name}
	sb, ok := loadedSounds[key]
	if !ok {
		f, err := resource.Open("minecraft", "sounds/"+name+".ogg")
		if err != nil {
			v, ok := assets.Objects[fmt.Sprintf("minecraft/sounds/%s.ogg", name)]
			if !ok {
				console.Text("Missing sound %s", key)
				if cb != nil {
					cb()
				}
				return
			}
			loc := fmt.Sprintf("./resources/%s", hashPath(v.Hash))
			f, err = os.Open(loc)
			if err != nil {
				console.Text("Missing sound %s", key)
				if cb != nil {
					cb()
				}
				return
			}
		}
		if snd.Stream {
			m := audio.NewMusic(f)
			m.SetVolume(vol)
			m.SetPitch(pitch)
			m.Play()
			currentMusic = append(currentMusic, music{Music: m, cb: cb, cat: cat, vol: baseVol})
			return
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			panic(err)
		}
		sb = audio.NewSoundBufferData(data)
		loadedSounds[key] = sb
	}
	var s audio.Sound
	n := true
	for _, sn := range soundList {
		if sn.Status() == audio.StatStopped {
			s = sn
			n = false
			break
		}
	}
	if n {
		if len(soundList) >= 100 {
			console.Component(
				format.Build("WARN: Skipping playing sound due to limit").
					Color(format.Yellow).Create(),
			)
			return
		}
		s = audio.NewSound()
		soundList = append(soundList, s)
	}
	s.SetBuffer(sb)
	s.SetVolume(vol)
	s.SetMinDistance(5)
	s.SetAttenuation(0.008)
	s.SetPitch(pitch)
	s.Play()
	if rel {
		s.SetRelative(true)
		s.SetPosition(pos.X(), pos.Y(), pos.Z())
	} else {
		s.SetRelative(false)
	}
}