Databaseinfo

From StarMade Wiki

Structure of database

Database of blocks is transformed from game datafiles. Two file (Main and Sub) are generated to reduce case by blocks. Template:Db/Version/0.xxx.xxx/file

templates are :

'"DbParser"' rename unwanted type, handle image options and send to '"Db"'

'"Db"' (and DbSub) choose the template (Main and Sub, databases) who have the requested data and ask to Version wich version (folder ) go to.

'"Version"' give '"LastVersion"'or the version ask. '"LastVersion"' store the default version.

'"Main"' and '"Sub"' are stored in 0.xxx.xxx and share data of each blocks to light process. ie : tempalte/Db/0.201.133/Main

More info here : code

Update Database

  1. You have to create a page Db/Version/0.xxx.xxx of the number of version.
  2. You have to get '"Main"' and '"Sub"' page in the new 0.xxx.xxx/ folder done.
  3. You must add version added in '"Version"' page.
  4. If it is the last stable version, you have to put it as default version ( replace in '"LastVersion"' )

Location of game files

2 files are needed : BlockConfig.xml and BlockTypes.properties they are in :

  • linux : $$linuxinstalldir$$/Starmade/data/config
  • Windows : Program files\Starmade\data\config
  • Steam : steam\steam\steamapps\common\StarMade\data\config

Regex and xslt are used to transform original files of games.

Regexp online usage

You can use https://www.freeformatter.com/regex-tester.html as it allow to handle big text. You have to set option (flags) in regex : only /m and /g. You have to put a regular expression , a text to parse, and a line to replace with. Result on this website can be copy-pasted by click first caracter, go the end of list (scroll bar) and [SHIFT]+ click on last caracter. In all code i write above there is a line of regular expression and one of replace. If no replace line, leave blank (without space).


XslT online usage

For xslt you can use : https://xsltfiddle.liberty-development.net/ you content of your file upper left, you past xslt "modifier" upper right, and you get result in bottom left.


Get the database from game files :

Make copy of '"BlockConfig.xml"', open this copy and add a line to the start of file (before <config>) copy the content of '"BlockTypes.properties"' to the beginning of '"BlockConfig.xml"' (where you add line). Now you have to use regex to modify this file.

copy the content of '"BlockConfig.xml"' (get with prorperties on the beginning)

Regex :

(\n([\w\(\)\\\/]*?)=\d*)(?=[\s\S]*(name="(.*?)".*?type="\2"))

Replace with :

$1=$4

move to end

(Copy the result in the tester field to be parsed !) Regex :

(#[\s\S]*?(?:[\w\(\)]*?=\d*?)*\s*?)(<Config>[\s\S]*<\/Config>)

Replace with :

$2\r$1


Apply ID and subnames

Regex :

(Block.*?type=")([\w\(\)]*?)(?="[\s\S]*?\2=(\d+))|(?:(<Item count="\d*">)|(<Element>))(\w*?)(?=<[\s\S]*?\6=\d+=(.*))

Replace with :

$5$1$4$7$3

DIVIDE IN TWO FILE, work on sub : order subTable data

Now, we have to work on the two futur page separatly. create two text file : one named Main.txt and one named sub.txt Fill it with the same content.

Apply this on sub.txt only :

<\/(?:Element|Chamber.*)>\s*\n\s*<(?:Element>|Chamber)|(<)(General)(Chamber(>))([\w ]*).*\n\s*\<Chamber(?=\w)|\n\s*<Element>(.*?)<\/Element>\n(?!<Element)|(?<=Consistence>)\n\s*(<Item) count="(\d+)"(>)|<\/Item>\s*\n\s*<Item count="(\d*)">|([\w ]*)(?=<\/Item>\s*\n\s*<Item)|,( \d*)(?=.*type)
$11$10$7$9$8$1$3$2$4$5$6|$12

SUB.TXT Remove all data unwanted :

in order : remove all info tag "", starting line white space, remove Useless lines, delete useless data, shorten data names. remove all before and after <element> tags

\n<Element>(?=[A-Z])|\s*?<(?=!--)[\s\S]*?-->|(?<=\n)\s*?(?=<)|\n.*(?:<Armour>|Consistence\/>|<Hitpoints>|<ArmorEffect[\s\S]*?\/\/ArmorEffect|<StructureHP|<Animate|<InShop|<ReactorH|<Mass|Placable|LightSource|Deprec|<ProducedIn|<BasicResource|<ArmorHP|Transpar|Orientatio|<CubatomCom[\s\S]*?\<\/CubatomCom|<InventoryGroup|<BlockComputerR|<Slab|<StyleId|<ReactorGeneralI|<Enterable|<IndividualS|<HasActivat|<BlockSty|<LightSource>|<RecipeBuyRe[\s\S]*?ipeBuyResource>|<Door>|SensorInput|<ResourceInjec|LightSourceColo|ExtendedText|OnlyDrawnI|LodShapeFr|LowHpSett|FactoryBakeTime|OldHitpoint|CanActivate|Physical).*|(?<=Desc)ription(?=>)|(?<! C)(?<=C)on(?=troll)|(?<! Contr)(?<=Contr)ol|(?<=CombinationControll)er|(?<=Controll)ed(?=By)|(?<=\|)\s*?<Element>|(?<=\/Chamber)AppliesTo|(?<=[0-9a-z])<\/Element>\n|Combination(?=Control)|(?<=Exp)losion(?=Absorbtion)|(?<=ExplosionAbsorb)tion|icon="[0-9]*"\s|type=".*?"|<Config>\s|(?<=GeneralChamber>)[\s]*<Chamber>[\s\S]*<\/Chamber>(?=\s*?<Block icon="914")|(?<=\s<\/Element>)\s+<Recipes[\s\S]*


(No replace here, only remove data)

MAIN.TXT remove data

\s*?<(?=!--)[\s\S]*?-->|(?<=\n)\s*?(?=<)|(?<=GeneralChamber>)[\s]*<Chamber>[\s\S]*<\/Chamber>(?=\s*?<Block icon="914")|\n.*(?:Consistence\/>|<Description>|<BasicResourceF|<Consistence[\s\S]*?mConsistence\/|<CubatomCom[\s\S]*?\<\/CubatomCom|<ControlledB[\s\S]*?\/ControlledBy>|<Controlling[\s\S]*?\/Controlling>|<RecipeBuyRe[\s\S]*?ipeBuyResource>|<InventoryGroup|<BlockComputerR|<Slab|<StyleId|<\w*?Chamber\w*?>.*<\/\w*?Chamber\w*?>|<ReactorGeneralI|<Enterable|<InRecip|<Door>|SensorInput|<ResourceInjec|ExtendedText|OnlyDrawnI|LodShapeFr|LowHpSett|OldHitpoint|ExplosionAbsorbtion|CombinationController|BlockResourceType|Price|Orientation|CanActivate|Physical|Volume).*|(?<=Hitp)oints|(?<=H)it(?=points>)|(?<=Armo)u(?=r>)|(?<=Armor)Value|\n.*<\/?EffectArmor>|ProducedIn|(?<=Light)Source|(?<=SideTex)turesPointTo(?=Orient)|(?<=SideTexturesPointToOrient)ation|(?<=C)ombinationCon(?=troller)|rmor(?=HPContribution)|(?<=Indiv)idual(?=Sides)|A(?=ArmorHPContribution)|textureId.*?" |(?<=ArmorHP)Contribution|tructure(?=HPContribution)|(?<=StructureHP)Contribution|<Config>|(?<=\s<\/Element>)\s+<Recipes[\s\S]*

Xslt

Now we have to remove xml formatting and put categories on the good place. You have to parse both file Main.txt. and Sub.txt

With this two xslt codes (se explain before if needed):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	exclude-result-prefixes="xs"
	version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:variable name="sorted-items" as="element(Block)*">
              <xsl:perform-sort select="descendant::Block">
                  <xsl:sort select="@name"/>
              </xsl:perform-sort>
          </xsl:variable>
          <xsl:sequence select="$sorted-items!root(snapshot())"/>
      </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>


and  : (dont forget to copy result in the parse window !)

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>



    <xsl:template match="*[@* or not(*)] ">
      <xsl:if test="not(*)">
         <xsl:apply-templates select="self::*" mode="path"/>
         <xsl:value-of select="concat('=',., ' ')"/>
         <xsl:text>
</xsl:text>
        </xsl:if>
        <xsl:apply-templates select="@*|*"/>
    </xsl:template>


    <xsl:template match="*" mode="path">
<xsl:choose>
        <xsl:when test="@name">
        <xsl:text>∼∼∼</xsl:text>
        <xsl:value-of select="concat('|', @name, '={{#switch:{{{2}}}')"/>

        </xsl:when>
     <xsl:otherwise>
        <xsl:value-of select="concat('|', name())"/>
   </xsl:otherwise>
</xsl:choose>
    </xsl:template>

    <xsl:template match="@*">
        
<xsl:choose>
        <xsl:when test="name()='name'">
            <xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
            <xsl:text>
</xsl:text>
            <xsl:value-of select="concat('|link=', ., ' ')"/>
        </xsl:when>
        <xsl:when test="name()='type'">
            <xsl:apply-templates select="self::*" mode="path"/>
	        <xsl:text>
</xsl:text>
            <xsl:value-of select="concat('|', name(), '=', ., ' ')"/>
            <xsl:text>
</xsl:text>
        </xsl:when>
   <xsl:otherwise>
            <xsl:apply-templates select="self::*" mode="path"/>
        	<xsl:text>
</xsl:text>
            <xsl:value-of select="concat('|', name(), '=', ., ' ')"/>
   </xsl:otherwise>
</xsl:choose>
    </xsl:template>
</xsl:stylesheet>

So, now you have Main.txt and Sub.tx without xml formatting Come back to regexp :

Sub.txt : Replace wrong symbole in Chamber created subsection

&gt;
=

Sub.txt : make table storage for multivariable blocks Type : controll(ing/ed)

\|(CtrlBy|Ctrling)=(.*)
|$1={{tablebox|{{{2}}}|{{{3}}}|{{{4}}}|$2}}

Sub.txt : make table storage for multivariable blocks Type : consistence,chamber and

\|(Item|Chamber)=(.*)
|$1$3={{tablebox|{{{1}}}|{{{3}}}|{{{4}}}|$2$4}}

still Sub.txt 2nd step :

\|(textureId)=((\|? ?\d+)*) ?
|$1={{3dblock|{{{1}}}|{{{3}}}|{{{4}}}|$2}}

Main.txt

Write all category in blocks tags and format it a the end (no priority request).

(\n?\|icon=\d* ?)(.*Element)\|(\w*)(?:\|(\w*))?(?:\|(\w*))?(?:\|(\w*))?([\s\S]*?\|Hp=\d* ?\n)
$2$7|cat=$3\r|cat2=$4\r|cat3=$5\r|cat4=$6$1\r


SUB.TXT remove cat

(?<=\|Element)\|(?!Element)(\w*)(?:\|(\w*))?(?:\|(\w*))?(?:\|(\w*))?


MAIN.TXT + SUB.TXT

Divide case in alphabetival nest to light request process

\n(\|.*?)?\|Element.*?\W(\|([B-Z])[\s\S]*(?:\n\|Element\|.*?\W\|\3\w*).*)
\r}}\r}}\r|$3={{#switch:{{{1}}}\r$2


Again on both file :

\n(\|.*?)(?:\|Element)(?:\|Element)?[\W]{3}(.*\n)
}}\r$2$1\n


Next step on the two files : Remove added position characters, replace by lasts {} and position icon

\|Element.*?[\W]{3}(?=\|)
}}\r


Both MAIN.TXT and SUB.TXT Finally, Write last enclosing fonction.

}}([\s\S]*\S)
{{#switch:{{padleft:|1|{{{1}}}}}<!-- Search by first letter of request to divide 1 branche cases -->\r|A={{#switch:{{{1}}}\r$1\r}}\r}}\r}}

Come back to wiki

now you have to create a page Main ( in Db/Version/0.xxx.xxx) with content of Main.txt and a page Sub with content of Sub.txt.


You have to add a line in '"Version"' :

-->|0.999.999=0.999.999<!--


If It is the latest stable version you have to change the number of version in '"LastVersion"', then the directory by default for all queries will be the new. (replace by old to instant revert)