Skip to content

v1.0.0 #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7be3b4d
Began refactor for v2
Galaco Sep 24, 2023
66451e2
Clean up public API
Galaco Sep 25, 2023
363e396
Marked unknown dispinfo data as unknown
Galaco Sep 25, 2023
e6d937d
Readme and test cleanups
Galaco Sep 25, 2023
718e259
Game lump header correct export
Galaco Sep 25, 2023
777c8af
Fixed game lump export
Galaco Sep 25, 2023
fd75d64
Use generic FromBytes
Galaco Sep 25, 2023
cccb6f6
Fix worldlighthdr export
Galaco Sep 25, 2023
06a783b
v21 writer next steps
Galaco Sep 25, 2023
b01900c
Updated flag names
Galaco Sep 26, 2023
43cf945
More cleanups
Galaco Sep 26, 2023
e4db02d
Optimizations
Galaco Sep 26, 2023
ba2eaf3
Cleanup
Galaco Sep 26, 2023
b3d05e7
Json tagged all data
Galaco Sep 26, 2023
308c99c
Code style cleanups
Galaco Sep 26, 2023
0507b16
Writer header debugging
Galaco Sep 27, 2023
a8c8a9f
Renamed packages
Galaco Sep 27, 2023
cc99ff4
Export lump header
Galaco Sep 27, 2023
b4e1333
Mostly fix writing body
Galaco Sep 27, 2023
772f2b5
ar_baggage writer binary identical
Galaco Sep 27, 2023
d673a72
Writer optimizations
Galaco Sep 27, 2023
465acff
Fixed silly byte alignment mistake
Galaco Sep 27, 2023
3b59d85
Optimized game lump offset usage
Galaco Sep 27, 2023
089f147
Add dust2 test sample
Galaco Sep 27, 2023
d09e71d
Clean up lump parsing
Galaco Sep 27, 2023
ea8f324
More optimizations
Galaco Sep 27, 2023
9ecc483
v20 + v21 exports using custom tags
Galaco Sep 29, 2023
5b3f082
Add code samples
Galaco Sep 29, 2023
39630f7
Correctly write gamedata lump if offset changes
Galaco Sep 30, 2023
824f28c
Lump 10: Leaf read/write optimizations
Galaco Sep 30, 2023
34dcdea
Work towards correct leafambient lighting export on de_nuke
Galaco Sep 30, 2023
f936906
Corrected writer log
Galaco Oct 1, 2023
8c3e21b
Basic entdata parsing implementation
Galaco Oct 2, 2023
883c4a7
made rawBytes private in favour of public Unimplemented
Galaco Oct 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .circleci/config.yml

This file was deleted.

22 changes: 22 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Test and coverage
on:
push:
branches:
- '*'
pull_request:
branches: [main]
jobs:
test:
name: Run tests
runs-on: 'ubuntu-latest'
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Install Go 1.19.0
uses: actions/setup-go@v2
with:
go-version: '1.19.0'
- name: Run coverage
run: go test ./... -race -coverpkg=./libs/... -coverprofile=coverage.out -covermode=atomic
77 changes: 55 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
[![GoDoc](https://godoc.org/github.com/Galaco/bsp?status.svg)](https://godoc.org/github.com/Galaco/bsp)
[![Go report card](https://goreportcard.com/badge/github.com/galaco/bsp)](https://goreportcard.com/badge/github.com/galaco/bsp)
[![GolangCI](https://golangci.com/badges/github.com/galaco/bsp.svg)](https://golangci.com)
[![Build Status](https://travis-ci.com/Galaco/bsp.svg?branch=master)](https://travis-ci.com/Galaco/bsp)
[![CircleCI](https://circleci.com/gh/Galaco/bsp/tree/master.svg?style=svg)](https://circleci.com/gh/Galaco/bsp/tree/master)
[![codecov](https://codecov.io/gh/Galaco/bsp/branch/master/graph/badge.svg)](https://codecov.io/gh/Galaco/bsp)

# Bsp
Go library for handling Source Engine .bsp map files.
The most comprehensive library for reading and writing Source Engine .bsp map files.

### Features:
* Read support for (most) non-xbox360 BSPs (v20,21). v19 support limited, may work
Expand Down Expand Up @@ -72,7 +71,11 @@ The following lumps currently have a full implementation for v20 & v21 BSPs (tes
60: OverlayFades
```

##### This library may reorganise lump order during the first export. This is intentional to handle lump resizing, but will change your checksum if you export without changes.
Lumps not listed here are parsed and available as `[]byte` format.

Note: Some lumps in some BSP versions have data with unidentified purpose. These fields are available as byte arrays.
Please submit an issue or a PR if you can help fill in any of these fields.


# Usage

Expand All @@ -83,35 +86,65 @@ lump (entdata is a single json-like string) of a specified .bsp to console.
package main

import (
"github.com/galaco/bsp"
"github.com/galaco/bsp/lumps"
"log"
"os"
"github.com/galaco/bsp"
"github.com/galaco/bsp/lump"
"log"
"os"
)

func main() {
f,_ := os.Open("de_dust2.bsp")

// Create a new bsp reader
reader := bsp.NewReader(f)

// Read buffer
file,err := reader.Read()
if err != nil {
log.Fatal(err)
}
f.Close()

lump := file.Lump(bsp.LumpEntities).(*lumps.Entities)
log.Println(lump.GetData())
f, err := os.Open("de_dust2.bsp")
if err != nil {
log.Fatal(err)
}
defer f.Close()

// Create a new bsp reader
reader := bsp.NewReader()

// Read buffer
file, err := reader.Read(f)
if err != nil {
log.Fatal(err)
}

entdata := (file.Lumps[bsp.LumpEntities]).(*lump.Entdata)
log.Println(entdata.Contents())
}
```

There are more usage examples available in the `examples/` directory.

## Exporting BSPs

This library supports writing BSPs. It aims to preserve identical binaries where possible, but this is not guaranteed
due to wide-ranging difference in format across games (and even within the same game!).
For example:
* Counterstrike: Source
* de_dust2 Lump 59 (MapFlags) has 0 flags set, a the 4byte lump is written. Format is BSP v20.
* de_nuke Lump 59 (MapFlags) has 0 flags set, but the lump is not written. Format is BSP v20.

There are plenty of other scenarios where this can occur, and in a way that we cannot guess with certainty what the
expected behaviour should be. By default, this library assumes that structures that contain > 0 bytes are written,
but this behaviour can be overridden (see examples).

## Overriding lumps.

Lumps can be overridden by using the `NewReaderWithOptions` function, and passing a custom `LumpResolver`. A `LumpResolver` is
responsible for return a new instance of whatever lump implementation you wish to use for a particular Lump index and BSP version.
See examples for more details.

### Lump 35: Game Lump

The game lump has special rules, because of the unusual use of absolute file offsets. If you wish to override the game lump with
your own implementation, then you must implement the `lump.GameGeneric` interface on your custom lump definition.


## Real World examples
* Proof of concept BSP viewer: [https://github.com/Galaco/kero](https://github.com/Galaco/kero)
* Insert game_text newline placeholder characters (avoids Hammer crash) as a compile step: [https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang](https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang)
* Bspzip filelist generator from a mountable resource directory: [https://github.com/Galaco/bspzip-traverser](https://github.com/Galaco/bspzip-traverser)


# Contributing
All contributions welcome. Known unsupported games/maps are especially useful.
All contributions welcome, in particular any maps that are found to be incompatible.
Binary file removed ar_baggage.bsp.gz
Binary file not shown.
53 changes: 23 additions & 30 deletions bsp.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
package bsp

import "github.com/galaco/bsp/lumps"

// Bsp is the root .bsp filetype container.
// Consists of a 1036byte header and 64 lump blocks.
type Bsp struct {
header Header
lumps [64]Lump
Header Header `json:"header"`
Lumps [64]Lump `json:"lumps"`
}

// Header is the Bsp header. Contains format and lump layout data.
// Do not trust lump information between import and export
type Header struct {
Id int32
Version int32
Lumps [64]HeaderLump
Revision int32
Id int32 `json:"id"`
Version int32 `json:"version"`
Lumps [64]HeaderLump `json:"lumps"`
Revision int32 `json:"revision"`
}

// HeaderLump contains layout information for a given lump, stored in the Header.
type HeaderLump struct {
Offset int32
Length int32
Version int32
Id [4]byte
}

// Header gets the header for a bsp.
func (bsp *Bsp) Header() *Header {
return &bsp.header
}

// Lump gets the lump for a given id.
func (bsp *Bsp) Lump(index LumpId) lumps.ILump {
return bsp.RawLump(index).Contents()
}

// RawLump gets the lump for a given id.
func (bsp *Bsp) RawLump(index LumpId) *Lump {
return &bsp.lumps[int(index)]
// Offset is the offset into the file (in bytes).
Offset int32 `json:"offset"`
// Length is the lump length (in bytes).
Length int32 `json:"length"`
// Version is the lump version.
Version int32 `json:"version"`
// ID is lump ident code.
// If the lump is compressed then treat as an integer that represents the decompressed size.
ID [4]byte `json:"id"`
}

// SetLump sets the lump data for a given id.
func (bsp *Bsp) SetLump(index LumpId, lump Lump) {
bsp.lumps[int(index)] = lump
// Lump interface.
type Lump interface {
// FromBytes imports a []byte to a defined lump structure(s).
FromBytes([]byte) error
// ToBytes exports lump structure back to []byte.
ToBytes() ([]byte, error)
// SetVersion sets bsp version of lump.
SetVersion(version int32)
}
Loading