mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 01:57:01 +00:00
Adds a Fulpstation Changelog (#1345)
* Commits a highly incomplete version of a Fulpstation changelog. * Further develops a basic, copied version of /tg/'s changelog. * Makes the changelog actually semi-functional. * Finalizes a few things...
This commit is contained in:
committed by
GitHub
parent
5a63a340bf
commit
16aeb51d7b
@@ -249,6 +249,11 @@ GLOBAL_PROTECT(tracy_init_reason)
|
||||
var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml")
|
||||
GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently
|
||||
|
||||
// FULP EDIT //
|
||||
var/latest_fulp_changelog = file("[global.config.directory]/../fulp_modules/data/html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml")
|
||||
GLOB.fulp_changelog_hash = fexists(latest_fulp_changelog) ? md5(latest_fulp_changelog) : 0
|
||||
// FULP EDIT END //
|
||||
|
||||
if(GLOB.round_id)
|
||||
log_game("Round ID: [GLOB.round_id]")
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
/// Cached changelog size, to detect new changelogs since last join
|
||||
var/lastchangelog = ""
|
||||
|
||||
/// FULP EDIT ///
|
||||
/// Same as var above but for Fulpstation's changelog.
|
||||
var/last_fulp_changelog = ""
|
||||
/// FULP EDIT END ///
|
||||
|
||||
/// List of ROLE_X that the client wants to be eligible for
|
||||
var/list/be_special = list() //Special role selection
|
||||
|
||||
|
||||
88
fulp_modules/data/html/changelogs/fulp_changelog.dm
Normal file
88
fulp_modules/data/html/changelogs/fulp_changelog.dm
Normal file
@@ -0,0 +1,88 @@
|
||||
//-----------------------------------------//
|
||||
// Fulpstation's Changelog //
|
||||
//-----------------------------------------//
|
||||
|
||||
/***
|
||||
* This file contains all DM code related to Fulpstation's changelog.
|
||||
*
|
||||
* Most of this is just a very rough copying of existing /tg/ code with "fulp" appended to it,
|
||||
* so credit for all of it goes to the various people who made /tg/'s changelog.
|
||||
**/
|
||||
|
||||
|
||||
/// FULP CHANGELOG DATUM ///
|
||||
|
||||
GLOBAL_DATUM(fulp_changelog_tgui, /datum/fulp_changelog)
|
||||
GLOBAL_VAR_INIT(fulp_changelog_hash, "")
|
||||
|
||||
/datum/fulp_changelog
|
||||
var/static/list/fulp_changelog_items = list()
|
||||
|
||||
/datum/fulp_changelog/ui_state()
|
||||
return GLOB.always_state
|
||||
|
||||
/datum/fulp_changelog/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if (!ui)
|
||||
ui = new(user, src, "FulpChangelog")
|
||||
ui.open()
|
||||
|
||||
/datum/fulp_changelog/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(action == "get_month")
|
||||
var/datum/asset/fulp_changelog_item/fulp_changelog_item = fulp_changelog_items[params["date"]]
|
||||
if (!fulp_changelog_item)
|
||||
fulp_changelog_item = new /datum/asset/fulp_changelog_item(params["date"])
|
||||
fulp_changelog_items[params["date"]] = fulp_changelog_item
|
||||
return ui.send_asset(fulp_changelog_item)
|
||||
|
||||
/datum/fulp_changelog/ui_static_data()
|
||||
var/list/data = list( "dates" = list() )
|
||||
var/regex/ymlRegex = regex(@"\.yml", "g")
|
||||
|
||||
for(var/archive_file in sort_list(flist("fulp_modules/data/html/changelogs/archive/")))
|
||||
var/archive_date = ymlRegex.Replace(archive_file, "")
|
||||
data["dates"] = list(archive_date) + data["dates"]
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/// CHANGELOG VERB ///
|
||||
|
||||
/client/verb/fulp_changelog()
|
||||
set name = "Changelog"
|
||||
set category = "OOC"
|
||||
if(!GLOB.fulp_changelog_tgui)
|
||||
GLOB.fulp_changelog_tgui = new /datum/fulp_changelog()
|
||||
|
||||
GLOB.fulp_changelog_tgui.ui_interact(mob)
|
||||
if(prefs.last_fulp_changelog != GLOB.fulp_changelog_hash)
|
||||
prefs.last_fulp_changelog = GLOB.fulp_changelog_hash
|
||||
prefs.save_preferences()
|
||||
winset(src, "infowindow.changelog", "font-style=;")
|
||||
|
||||
|
||||
/// FULP CHANGELOG ITEM ASSET ///
|
||||
|
||||
/datum/asset/fulp_changelog_item
|
||||
_abstract = /datum/asset/fulp_changelog_item
|
||||
var/item_filename
|
||||
|
||||
/datum/asset/fulp_changelog_item/New(date)
|
||||
item_filename = SANITIZE_FILENAME("[date].yml")
|
||||
SSassets.transport.register_asset(item_filename, file("fulp_modules/data/html/changelogs/archive/" + item_filename))
|
||||
|
||||
/datum/asset/fulp_changelog_item/send(client)
|
||||
if (!item_filename)
|
||||
return
|
||||
. = SSassets.transport.send_assets(client, item_filename)
|
||||
|
||||
/datum/asset/fulp_changelog_item/get_url_mappings()
|
||||
if (!item_filename)
|
||||
return
|
||||
. = list("[item_filename]" = SSassets.transport.get_asset_url(item_filename))
|
||||
|
||||
|
||||
// See 'world.dm' for a changelog-related Fulp edit. //
|
||||
@@ -1,7 +1,5 @@
|
||||
## List of all TG edits:
|
||||
|
||||
- .github/workflows/compile_changelogs.yml > Same as above.
|
||||
|
||||
- code/datums/greyscale/_greyscale_config.dm > Adds our greyscales folder to the sanity check
|
||||
|
||||
- code/game/area/areas/shuttles.dm > Plays ApproachingFulp instead of ApproachingTG
|
||||
@@ -18,6 +16,14 @@
|
||||
|
||||
- tools/pull_request_hooks/autoChangelog.js > Changes changelog folder to fulp_modules/data/html/changelogs, to preserve them across TGUs.
|
||||
|
||||
- .github\workflows\compile_changelogs.yml > Same as above.
|
||||
|
||||
- code\game\world.dm > Marked by a "FULP EDIT" comment; copies a bit of code to make 'GLOB.fulp_changelog_hash' functional.
|
||||
|
||||
- code\modules\client\preferences.dm > Marked by a "FULP EDIT" comment; gives clients the 'last_fulp_changelog' var.
|
||||
|
||||
- interface\interface.dm > Changes the value of 'name' on '/client/verb/changelog' to "/TG/ Changelog"
|
||||
|
||||
## All Fulp files not contained within /fulp_modules/
|
||||
|
||||
- code/__DEFINES/fulp_defines > Contains all of our defines
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
|
||||
/client/verb/changelog()
|
||||
set name = "Changelog"
|
||||
set name = "/TG/ Changelog"
|
||||
set category = "OOC"
|
||||
if(!GLOB.changelog_tgui)
|
||||
GLOB.changelog_tgui = new /datum/changelog()
|
||||
|
||||
@@ -6526,6 +6526,7 @@
|
||||
#include "fulp_modules\_signals\bloodsuckers.dm"
|
||||
#include "fulp_modules\_signals\misc.dm"
|
||||
#include "fulp_modules\_signals\nanites.dm"
|
||||
#include "fulp_modules\data\html\changelogs\fulp_changelog.dm"
|
||||
#include "fulp_modules\features\admin_chicanery\smites\catification.dm"
|
||||
#include "fulp_modules\features\antagonists\antag_tips\antag_tip_integration.dm"
|
||||
#include "fulp_modules\features\antagonists\antag_tips\preference.dm"
|
||||
|
||||
371
tgui/packages/fulpui-patches/FulpChangelog.jsx
Normal file
371
tgui/packages/fulpui-patches/FulpChangelog.jsx
Normal file
@@ -0,0 +1,371 @@
|
||||
import dateformat from 'dateformat';
|
||||
import yaml from 'js-yaml';
|
||||
import { Component, Fragment } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dropdown,
|
||||
Icon,
|
||||
Section,
|
||||
Stack,
|
||||
Table,
|
||||
} from '../tgui/components';
|
||||
import { classes } from 'common/react';
|
||||
|
||||
import { resolveAsset } from '../tgui/assets';
|
||||
import { useBackend } from '../tgui/backend';
|
||||
import { Window } from '../tgui/layouts';
|
||||
|
||||
const icons = {
|
||||
add: { icon: 'check-circle', color: 'green' },
|
||||
admin: { icon: 'user-shield', color: 'purple' },
|
||||
balance: { icon: 'balance-scale-right', color: 'yellow' },
|
||||
bugfix: { icon: 'bug', color: 'green' },
|
||||
code_imp: { icon: 'code', color: 'green' },
|
||||
config: { icon: 'cogs', color: 'purple' },
|
||||
expansion: { icon: 'check-circle', color: 'green' },
|
||||
experiment: { icon: 'radiation', color: 'yellow' },
|
||||
image: { icon: 'image', color: 'green' },
|
||||
imageadd: { icon: 'tg-image-plus', color: 'green' },
|
||||
imagedel: { icon: 'tg-image-minus', color: 'red' },
|
||||
qol: { icon: 'hand-holding-heart', color: 'green' },
|
||||
refactor: { icon: 'tools', color: 'green' },
|
||||
rscadd: { icon: 'check-circle', color: 'green' },
|
||||
rscdel: { icon: 'times-circle', color: 'red' },
|
||||
server: { icon: 'server', color: 'purple' },
|
||||
sound: { icon: 'volume-high', color: 'green' },
|
||||
soundadd: { icon: 'tg-sound-plus', color: 'green' },
|
||||
sounddel: { icon: 'tg-sound-minus', color: 'red' },
|
||||
spellcheck: { icon: 'spell-check', color: 'green' },
|
||||
map: { icon: 'map', color: 'green' },
|
||||
tgs: { icon: 'toolbox', color: 'purple' },
|
||||
tweak: { icon: 'wrench', color: 'green' },
|
||||
unknown: { icon: 'info-circle', color: 'label' },
|
||||
wip: { icon: 'hammer', color: 'orange' },
|
||||
};
|
||||
|
||||
export class FulpChangelog extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: 'Loading changelog data...',
|
||||
selectedDate: '',
|
||||
selectedIndex: 0,
|
||||
};
|
||||
this.dateChoices = [];
|
||||
}
|
||||
|
||||
setData(data) {
|
||||
this.setState({ data });
|
||||
}
|
||||
|
||||
setSelectedDate(selectedDate) {
|
||||
this.setState({ selectedDate });
|
||||
}
|
||||
|
||||
setSelectedIndex(selectedIndex) {
|
||||
this.setState({ selectedIndex });
|
||||
}
|
||||
|
||||
getData = (date, attemptNumber = 1) => {
|
||||
const { act } = useBackend();
|
||||
const self = this;
|
||||
const maxAttempts = 6;
|
||||
|
||||
if (attemptNumber > maxAttempts) {
|
||||
return this.setData(
|
||||
'Failed to load data after ' + maxAttempts + ' attempts',
|
||||
);
|
||||
}
|
||||
|
||||
act('get_month', { date });
|
||||
|
||||
fetch(resolveAsset(date + '.yml')).then(async (changelogData) => {
|
||||
const result = await changelogData.text();
|
||||
const errorRegex = /^Cannot find/;
|
||||
|
||||
if (errorRegex.test(result)) {
|
||||
const timeout = 50 + attemptNumber * 50;
|
||||
|
||||
self.setData('Loading changelog data' + '.'.repeat(attemptNumber + 3));
|
||||
setTimeout(() => {
|
||||
self.getData(date, attemptNumber + 1);
|
||||
}, timeout);
|
||||
} else {
|
||||
self.setData(yaml.load(result, { schema: yaml.CORE_SCHEMA }));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
data: { dates = [] },
|
||||
} = useBackend();
|
||||
|
||||
if (dates) {
|
||||
dates.forEach((date) =>
|
||||
this.dateChoices.push(dateformat(date, 'mmmm yyyy', true)),
|
||||
);
|
||||
this.setSelectedDate(this.dateChoices[0]);
|
||||
this.getData(dates[0]);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, selectedDate, selectedIndex } = this.state;
|
||||
const {
|
||||
data: { dates },
|
||||
} = useBackend();
|
||||
const { dateChoices } = this;
|
||||
|
||||
const dateDropdown = dateChoices.length > 0 && (
|
||||
<Stack mb={1}>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
className="Changelog__Button"
|
||||
disabled={selectedIndex === 0}
|
||||
icon={'chevron-left'}
|
||||
onClick={() => {
|
||||
const index = selectedIndex - 1;
|
||||
|
||||
this.setData('Loading changelog data...');
|
||||
this.setSelectedIndex(index);
|
||||
this.setSelectedDate(dateChoices[index]);
|
||||
window.scrollTo(
|
||||
0,
|
||||
document.body.scrollHeight ||
|
||||
document.documentElement.scrollHeight,
|
||||
);
|
||||
return this.getData(dates[index]);
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Dropdown
|
||||
autoScroll={false}
|
||||
options={dateChoices}
|
||||
onSelected={(value) => {
|
||||
const index = dateChoices.indexOf(value);
|
||||
|
||||
this.setData('Loading changelog data...');
|
||||
this.setSelectedIndex(index);
|
||||
this.setSelectedDate(value);
|
||||
window.scrollTo(
|
||||
0,
|
||||
document.body.scrollHeight ||
|
||||
document.documentElement.scrollHeight,
|
||||
);
|
||||
return this.getData(dates[index]);
|
||||
}}
|
||||
selected={selectedDate}
|
||||
width="150px"
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
className="Changelog__Button"
|
||||
disabled={selectedIndex === dateChoices.length - 1}
|
||||
icon={'chevron-right'}
|
||||
onClick={() => {
|
||||
const index = selectedIndex + 1;
|
||||
|
||||
this.setData('Loading changelog data...');
|
||||
this.setSelectedIndex(index);
|
||||
this.setSelectedDate(dateChoices[index]);
|
||||
window.scrollTo(
|
||||
0,
|
||||
document.body.scrollHeight ||
|
||||
document.documentElement.scrollHeight,
|
||||
);
|
||||
return this.getData(dates[index]);
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const header = (
|
||||
<Section>
|
||||
<h1>Fulpstation</h1>
|
||||
<p>
|
||||
<b>Please note: </b>
|
||||
this changelog would not be possible without the groundwork laid by
|
||||
/tg/station's contributors and so many others. Aside from its logged
|
||||
content, this changelog is an almost identical copy of /tg/station's,
|
||||
which can currently be found in the OOC tab under the "/TG/ Changelog"
|
||||
verb.
|
||||
</p>
|
||||
<p>
|
||||
<b>Thanks to: </b>
|
||||
/tg/station, Baystation 12, /vg/station, NTstation, CDK Station devs,
|
||||
FacepunchStation, GoonStation devs, the original Space Station 13
|
||||
developers, GitHub user celotajstg for adapting this changelog into
|
||||
TGUI, and countless others who have contributed to the game, issue
|
||||
tracker or wiki over the years.
|
||||
</p>
|
||||
<p>
|
||||
{'Recent GitHub contributors can be found '}
|
||||
<a href="https://github.com/fulpstation/fulpstation/pulse/monthly">
|
||||
here
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
{
|
||||
'You can also find a link to our discord at the front page of our wiki'
|
||||
}
|
||||
<a href="https://wiki.fulp.gg/"> here</a>.
|
||||
</p>
|
||||
{dateDropdown}
|
||||
</Section>
|
||||
);
|
||||
|
||||
const footer = (
|
||||
<Section>
|
||||
{dateDropdown}
|
||||
<h3>GoonStation 13 Development Team</h3>
|
||||
<p>
|
||||
<b>Coders: </b>
|
||||
Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob,
|
||||
Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
|
||||
</p>
|
||||
<p>
|
||||
<b>Spriters: </b>
|
||||
Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said
|
||||
No
|
||||
</p>
|
||||
<p>
|
||||
Traditional Games Space Station 13 is thankful to the GoonStation 13
|
||||
Development Team for its work on the game up to the
|
||||
{' r4407 release. The changelog for changes up to r4407 can be seen '}
|
||||
<a href="https://wiki.ss13.co/Pre-2016_Changelog#April_2010">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
{'Except where otherwise noted, Goon Station 13 is licensed under a '}
|
||||
<a href="https://creativecommons.org/licenses/by-nc-sa/3.0/">
|
||||
Creative Commons Attribution-Noncommercial-Share Alike 3.0 License
|
||||
</a>
|
||||
{'. Rights are currently extended to '}
|
||||
<a href="http://forums.somethingawful.com/">SomethingAwful Goons</a>
|
||||
{' only.'}
|
||||
</p>
|
||||
<h3>Traditional Games Space Station 13 License</h3>
|
||||
<p>
|
||||
{'All code after '}
|
||||
<a
|
||||
href={
|
||||
'https://github.com/tgstation/tgstation/commit/' +
|
||||
'333c566b88108de218d882840e61928a9b759d8f'
|
||||
}
|
||||
>
|
||||
commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at
|
||||
4:38 PM PST
|
||||
</a>
|
||||
{' is licensed under '}
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.html">GNU AGPL v3</a>
|
||||
{'. All code before that commit is licensed under '}
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html">GNU GPL v3</a>
|
||||
{', including tools unless their readme specifies otherwise. See '}
|
||||
<a href="https://github.com/tgstation/tgstation/blob/master/LICENSE">
|
||||
LICENSE
|
||||
</a>
|
||||
{' and '}
|
||||
<a href="https://github.com/tgstation/tgstation/blob/master/GPLv3.txt">
|
||||
GPLv3.txt
|
||||
</a>
|
||||
{' for more details.'}
|
||||
</p>
|
||||
<p>
|
||||
The TGS DMAPI API is licensed as a subproject under the MIT license.
|
||||
{' See the footer of '}
|
||||
<a
|
||||
href={
|
||||
'https://github.com/tgstation/tgstation/blob/master' +
|
||||
'/code/__DEFINES/tgs.dm'
|
||||
}
|
||||
>
|
||||
code/__DEFINES/tgs.dm
|
||||
</a>
|
||||
{' and '}
|
||||
<a
|
||||
href={
|
||||
'https://github.com/tgstation/tgstation/blob/master' +
|
||||
'/code/modules/tgs/LICENSE'
|
||||
}
|
||||
>
|
||||
code/modules/tgs/LICENSE
|
||||
</a>
|
||||
{' for the MIT license.'}
|
||||
</p>
|
||||
<p>
|
||||
{'All assets including icons and sound are under a '}
|
||||
<a href="https://creativecommons.org/licenses/by-sa/3.0/">
|
||||
Creative Commons 3.0 BY-SA license
|
||||
</a>
|
||||
{' unless otherwise indicated.'}
|
||||
</p>
|
||||
</Section>
|
||||
);
|
||||
|
||||
const changes =
|
||||
typeof data === 'object' &&
|
||||
Object.keys(data).length > 0 &&
|
||||
Object.entries(data)
|
||||
.reverse()
|
||||
.map(([date, authors]) => (
|
||||
<Section key={date} title={dateformat(date, 'd mmmm yyyy', true)}>
|
||||
<Box ml={3}>
|
||||
{Object.entries(authors).map(([name, changes]) => (
|
||||
<Fragment key={name}>
|
||||
<h4>{name} changed:</h4>
|
||||
<Box ml={3}>
|
||||
<Table>
|
||||
{changes.map((change) => {
|
||||
const changeType = Object.keys(change)[0];
|
||||
return (
|
||||
<Table.Row key={changeType + change[changeType]}>
|
||||
<Table.Cell
|
||||
className={classes([
|
||||
'Changelog__Cell',
|
||||
'Changelog__Cell--Icon',
|
||||
])}
|
||||
>
|
||||
<Icon
|
||||
color={
|
||||
icons[changeType]
|
||||
? icons[changeType].color
|
||||
: icons['unknown'].color
|
||||
}
|
||||
name={
|
||||
icons[changeType]
|
||||
? icons[changeType].icon
|
||||
: icons['unknown'].icon
|
||||
}
|
||||
/>
|
||||
</Table.Cell>
|
||||
<Table.Cell className="Changelog__Cell">
|
||||
{change[changeType]}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
})}
|
||||
</Table>
|
||||
</Box>
|
||||
</Fragment>
|
||||
))}
|
||||
</Box>
|
||||
</Section>
|
||||
));
|
||||
|
||||
return (
|
||||
<Window title="Changelog" width={675} height={650}>
|
||||
<Window.Content scrollable>
|
||||
{header}
|
||||
{changes}
|
||||
{typeof data === 'string' && <p>{data}</p>}
|
||||
{footer}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user