Skip to content

Instantly share code, notes, and snippets.

@apocalyptech
Created October 11, 2025 20:11
Show Gist options
  • Select an option

  • Save apocalyptech/2774ff6c7f2dcc17e8037a9a1bbd028a to your computer and use it in GitHub Desktop.

Select an option

Save apocalyptech/2774ff6c7f2dcc17e8037a9a1bbd028a to your computer and use it in GitHub Desktop.
<?php // vim: set expandtab tabstop=4 shiftwidth=4:
$dbhost = 'foo';
$dbuser = 'foo';
$dbpass = 'foo';
$dbname = 'foo';
$max_search_results = 100;
$errors = array();
$found_obj = false;
$searched_name = null;
$link_to = array();
$ref_by = array();
$search_results = array();
$dbh = new mysqli('p:' . $dbhost, $dbuser, $dbpass, $dbname);
if (mysqli_connect_errno())
{
array_push($errors, 'DB Connect error');
}
else
{
if (array_key_exists('name', $_REQUEST))
{
$searched_name = trim($_REQUEST['name']);
$searched_name = str_replace(array(' ', "\n", "\r", "\t", "\0", "\x0B"), '', $searched_name);
# Get the ID
$stmt = $dbh->prepare('select id from bl3object where name=?');
$stmt->bind_param('s', $searched_name);
$stmt->execute();
$stmt->bind_result($idnum);
$found_obj = $stmt->fetch();
$stmt->close();
if ($found_obj)
{
# Search for things we link to
$stmt = $dbh->prepare('select o.name from bl3refs r, bl3object o where r.to_obj=o.id and r.from_obj=?');
$stmt->bind_param('i', $idnum);
$stmt->execute();
$stmt->bind_result($to_name);
while ($stmt->fetch())
{
array_push($link_to, $to_name);
}
$stmt->close();
sort($link_to, SORT_STRING | SORT_FLAG_CASE);
# Search for things which reference us
$stmt = $dbh->prepare('select o.name from bl3refs r, bl3object o where r.from_obj=o.id and r.to_obj=?');
$stmt->bind_param('i', $idnum);
$stmt->execute();
$stmt->bind_result($from_name);
while ($stmt->fetch())
{
array_push($ref_by, $from_name);
}
$stmt->close();
sort($ref_by, SORT_STRING | SORT_FLAG_CASE);
}
else
{
$stmt = $dbh->prepare('select name from bl3object where name like ? limit ' . $max_search_results);
$wildcard_str = '%' . $searched_name . '%';
$stmt->bind_param('s', $wildcard_str);
$stmt->execute();
$stmt->bind_result($search_result);
while ($stmt->fetch())
{
array_push($search_results, $search_result);
}
$stmt->close();
sort($search_results, SORT_STRING | SORT_FLAG_CASE);
}
}
}
$dbh->close();
include('../../inc/apoc.php');
$page->set_title('Borderlands 3 Object Refs');
$page->add_changelog('October 11, 2019', 'Initial version');
$page->add_changelog('October 24, 2019', 'Updated with Bloody Harvest data (and October 3 patch data, which was missed originally)');
$page->add_changelog('November 25, 2019', array(
'Updated with Mayhem 4 / Maliwan Takedown data',
'Also corrected a bunch of incorrectly-pathed objects',
));
$page->add_changelog('November 26, 2019', 'Updated bl3refs.zip with MH4/MT data as well');
$page->add_changelog('November 27, 2019', 'Implemented very basic search functionality');
$page->add_changelog('December 3, 2019', 'Added in map objects, which were previously missing');
$page->add_changelog('December 12, 2019', 'Updated with initial preload patch data for DLC1 (Dandelion)');
$page->add_changelog('December 19, 2019', 'Updated with full DLC1 data');
$page->add_changelog('February 13, 2020', 'Updated with Broken Hearts data (and related patch)');
$page->add_changelog('March 16, 2020', 'Updated with data from Steam-integration patch');
$page->add_changelog('March 26, 2020', array(
'Updated with DLC2 (Hibiscus) preload patch data',
'Then later updated with full DLC2 data',
));
$page->add_changelog('April 23, 2020', 'Updated with Cartels and Mayhem 2.0 data');
$page->add_changelog('June 11, 2020', 'Updated with Guardian Takedown data');
$page->add_changelog('June 25, 2020', 'Updated with DLC3 (Geranium) data');
$page->add_changelog('July 23, 2020', 'Updated with July 23rd patch data');
$page->add_changelog('September 10, 2020', 'Updated with DLC4 (Alisma) data');
$page->add_changelog('November 9, 2020', 'Updated with DLC5 (Ixora / Designer\'s Cut) data');
$page->add_changelog('November 10, 2020', 'Updated with data from a separate update released after DLC5');
$page->add_changelog('January 21, 2021', 'Updated with data from today\'s patch');
$page->add_changelog('March 10, 2021', 'Added SQLite database version');
$page->add_changelog('April 8, 2021', 'Updated with DLC6 (Director\'s Cut) data');
$page->add_changelog('April 9, 2021', 'Re-generated sqlite3 database; it wasn\'t updated properly the first time');
$page->add_changelog('June 24, 2021', 'Updated with data from today\'s patch');
$page->add_changelog('August 5, 2021', 'Updated with data from today\'s patch');
$page->add_changelog('September 13, 2021', 'Updated with data from the 2021-09-09 patch');
$page->add_changelog('November 18, 2021', 'Updated with Vault Card 3 data/patch');
$page->add_changelog('June 11, 2022', 'Updated with June 1st\'s Playstation Crossplay data/patch');
$page->add_changelog('September 1, 2023', 'Updated with yesterday\'s customization-focused patch');
$page->add_changelog('July 19, 2024', 'Updated with yesterday\'s movie-related customization-focused patch');
$page->add_changelog('August 8, 2024', 'Updated with data from today\'s QOL patch');
$page->apoc_header();
if (count($errors) > 0)
{
echo "<div class=\"bad\">\n";
echo "<ul>\n";
foreach ($errors as $error)
{
echo "<li>$error</li>\n";
}
echo "</ul>\n";
echo "</div>\n";
}
?>
<p>
Enter a BL3 object name to get a list of other objects it links to, and
objects which link to it. Note that this database does not deal well
with objects with dynamic number suffixes, so those kinds of references
(like to many base-game cosmetics, for instance) probably won't show
up properly here. Also keep in mind this ignores all hotfix data, of
which there's a fair amount.
</p>
<form method="GET" action="index.php">
<input type="text" name="name" size="100" value="<?php
if ($searched_name != null and !$found_obj)
{
echo htmlentities($searched_name);
}
?>">
<input type="submit" value="Search!">
</form>
<?php
if ($searched_name != null)
{
echo '<h2>Results for: <tt>' . htmlentities($searched_name) . "</tt></h2>\n";
if ($found_obj)
{
echo "<h4>Objects this references:</h4>\n";
if (count($link_to) > 0)
{
echo "<ul class=\"compact\">\n";
foreach ($link_to as $link)
{
echo '<li><tt><a href="index.php?name=' . htmlentities($link) . '">' . htmlentities($link) . "</a></tt></li>\n";
}
echo "</ul>\n";
}
else
{
echo "<p><em>(none)</em></p>\n";
}
echo "<h4>Objects which reference this:</h4>\n";
if (count($ref_by) > 0)
{
echo "<ul class=\"compact\">\n";
foreach ($ref_by as $ref)
{
echo '<li><tt><a href="index.php?name=' . htmlentities($ref) . '">' . htmlentities($ref) . "</a></tt></li>\n";
}
echo "</ul>\n";
}
else
{
echo "<p><em>(none)</em></p>\n";
}
}
else
{
if (count($search_results) > 0)
{
if (count($search_results) == 1)
{
$result_text = '1 match';
}
elseif (count($search_results) == $max_search_results)
{
# Technically we could have *exactly* this count, but whatever.
$result_text = $max_search_results . '+ matches';
}
else
{
$result_text = count($search_results) . ' matches';
}
echo '<h4>Database search found ' . $result_text . ":</h4>\n";
echo "<ul class=\"compact\">\n";
foreach ($search_results as $search_result)
{
echo '<li><tt><a href="index.php?name=' . htmlentities($search_result) . '">' . htmlentities($search_result) . "</a></tt></li>\n";
}
echo "</ul>\n";
if (count($search_results) == $max_search_results)
{
echo '<p><em>(more results are in the database, but only ' . $max_search_results . " will be displayed)</em></p>\n";
}
}
else
{
echo "<p class=\"bad\">No results found!</p>\n";
}
}
}
?>
<p>
<strong>Note:</strong> One object has had its references pruned because they
had a *ton* of references, specifically <tt>/Game/Common/_Design/BPLevelAssetLists</tt>,
which references over 13k objects.
</p>
<p>
If you want a copy of the database itself, feel free to grab it in
either of a few ways:
</p>
<ul>
<li><tt><a href="bl3refs.sqlite3.zip">bl3refs.sqlite3.zip</a></tt> -
A <a href="https://www.sqlite.org/">SQLite database</a> version of
the data. As of March 10, 2021, this is what my
<a href="https://github.com/BLCM/bl3mods/tree/master/python_mod_helpers">bl3data</a>
library uses to grab references. Just download the file and unzip
it somewhere on your hard drive, then follow <tt>bl3data</tt>'s instructions
to point the code at the database file.</li>
<li><tt><a href="bl3refs.zip">bl3refs.zip</a></tt> - A MariaDB/MySQL
database dump. This is the database which actually powers this
website.</li>
</ul>
<? $page->apoc_footer(); ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment