func (fs *Filesystem) CreateDirectory(name string, p string) error {
	cleaned, err := fs.SafePath(path.Join(p, name))
	if err != nil {
		return err
	}
	return os.MkdirAll(cleaned, 0755)
}
Creates a new directory (name) at a specified path (p) for the server.
package filesystem
import (
	"bufio"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"emperror.dev/errors"
	"github.com/gabriel-vasile/mimetype"
	"github.com/karrick/godirwalk"
	ignore "github.com/sabhiram/go-gitignore"
	"github.com/pterodactyl/wings/config"
	"github.com/pterodactyl/wings/system"
)
type Filesystem struct {
	mu                sync.RWMutex
	lastLookupTime    *usageLookupTime
	lookupInProgress  *system.AtomicBool
	diskUsed          int64
	diskCheckInterval time.Duration
	denylist          *ignore.GitIgnore
	diskLimit int64
	root string
	isTest bool
}
func New(root string, size int64, denylist []string) *Filesystem {
	return &Filesystem{
		root:              root,
		diskLimit:         size,
		diskCheckInterval: time.Duration(config.Get().System.DiskCheckInterval),
		lastLookupTime:    &usageLookupTime{},
		lookupInProgress:  system.NewAtomicBool(false),
		denylist:          ignore.CompileIgnoreLines(denylist...),
	}
}
func (fs *Filesystem) Path() string {
	return fs.root
}
func (fs *Filesystem) File(p string) (*os.File, Stat, error) {
	cleaned, err := fs.SafePath(p)
	if err != nil {
		return nil, Stat{}, err
	}
	st, err := fs.Stat(cleaned)
	if err != nil {
		return nil, Stat{}, err
	}
	if st.IsDir() {
		return nil, Stat{}, newFilesystemError(ErrCodeIsDirectory, nil)
	}
	f, err := os.Open(cleaned)
	if err != nil {
		return nil, Stat{}, err
	}
	return f, st, nil
}
func (fs *Filesystem) Touch(p string, flag int) (*os.File, error) {
	cleaned, err := fs.SafePath(p)
	if err != nil {
		return nil, err
	}
	f, err := os.OpenFile(cleaned, flag, 0644)
	if err == nil {
		return f, nil
	}
	if !errors.Is(err, os.ErrNotExist) {
		return nil, errors.Wrap(err, "server/filesystem: touch: failed to open file handle")
	}
	if _, err := os.Stat(filepath.Dir(cleaned)); errors.Is(err, os.ErrNotExist) {
		if err := os.MkdirAll(filepath.Dir(cleaned), 0755); err != nil {
			return nil, errors.Wrap(err, "server/filesystem: touch: failed to create directory tree")
		}
		if err := fs.Chown(filepath.Dir(cleaned)); err != nil {
			return nil, err
		}
	}
	o := &fileOpener{}
	f, err = o.open(cleaned, flag, 0644)
	if err != nil {
		return nil, errors.Wrap(err, "server/filesystem: touch: failed to open file with wait")
	}
	_ = fs.Chown(cleaned)
	return f, nil
}
func (fs *Filesystem) Readfile(p string, w io.Writer) error {
	file, _, err := fs.File(p)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = bufio.NewReader(file).WriteTo(w)
	return err
}
func (fs *Filesystem) Writefile(p string, r io.Reader) error {
	cleaned, err := fs.SafePath(p)
	if err != nil {
		return err
	}
	var currentSize int64
	stat, err := os.Stat(cleaned)
	if err != nil && !os.IsNotExist(err) {
		return errors.Wrap(err, "server/filesystem: writefile: failed to stat file")
	} else if err == nil {
		if stat.IsDir() {
			return errors.WithStack(&Error{code: ErrCodeIsDirectory, resolved: cleaned})
		}
		currentSize = stat.Size()
	}
	br := bufio.NewReader(r)
	if err := fs.HasSpaceFor(int64(br.Size()) - currentSize); err != nil {
		return err
	}
	file, err := fs.Touch(cleaned, os.O_RDWR|os.O_CREATE|os.O_TRUNC)
	if err != nil {
		return err
	}
	defer file.Close()
	buf := make([]byte, 1024*4)
	sz, err := io.CopyBuffer(file, r, buf)
	fs.addDisk(sz - currentSize)
	return fs.Chown(cleaned)
}