-
Notifications
You must be signed in to change notification settings - Fork 100
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
Full TypeScript rewrite. Best type defs #651
base: master
Are you sure you want to change the base?
Conversation
src/lib/modules/commands.ts
Outdated
@@ -210,7 +210,7 @@ module.exports.server = function (serv, { version }) { | |||
|
|||
const count = opt.count !== undefined | |||
? opt.count | |||
: (type === 'all' || type === 'entity' ? serv.entities.length : 1) | |||
: (type === 'all' || type === 'entity' ? Object.keys(serv.entities).length : 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐛
src/lib/modules/communication.ts
Outdated
"_writeArray": (packetName: any, packetFields: any, players: any) => any | ||
"_writeNearby": (packetName: any, packetFields: any, loc: any) => any | ||
"getNearby": ({ world, position, radius }: { world: any; position: any; radius?: number | undefined }) => any | ||
"getNearbyEntities": ({ world, position, radius }: { world: any; position: any; radius?: number | undefined }) => any[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to remove destructure from types.
src/lib/modules/effects.ts
Outdated
entity.effects = {} | ||
for (let i = 1; i <= 23; i++) { // 23 in 1.8, 27 in 1.9 | ||
entity.effects[i] = null // Just so we know it's a real potion and not undefined/not existant | ||
} | ||
|
||
entity.sendEffect = (effectId, { amplifier = 0, duration = 30 * 20, particles = true, whitelist, blacklist = [] } = {}) => { | ||
if (!whitelist) whitelist = serv.getNearby(entity) | ||
if (entity.type === 'player' && [1].indexOf(effectId) !== -1) entity.sendAbilities() | ||
if (entity.type === 'player' && [1].indexOf(effectId) !== -1) (entity as Player).sendAbilities() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could turn entity into union of "common entity" and "player" so checks like entity.type === player would narrow the type to Player. But it's not possible since we re using interfaces for per-module extension and not types. So it would be easier to just mention this trick
src/lib/modules/placeBlock.ts
Outdated
const registry = require('prismarine-registry')(version) | ||
const blocks = registry.blocks | ||
|
||
player._client.on('block_place', async ({ direction, location, cursorY } = {}) => { | ||
const referencePosition = new Vec3(location.x, location.y, location.z) | ||
const block = await player.world.getBlock(referencePosition) | ||
block.position = referencePosition | ||
//@ts-ignore TODO | ||
block.direction = direction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why this pattern is widely used across prismarine projects, imo it shouldn't as it makes debugging hard
(cherry picked from commit 9748f4f)
remove almost all require's, make mcData typed (expose), make types ready for publishing! (cherry picked from commit e4be9d8)
add block renames (cherry picked from commit b9a2813)
(cherry picked from commit f324dc4)
…rnal remove api.md for now fix gentypes (cherry picked from commit dd3253e)
…r overworld (cherry picked from commit 8297df2)
(cherry picked from commit 9d72f86)
(cherry picked from commit 46edddc)
(cherry picked from commit ba37e8d)
(cherry picked from commit 692f062)
No top level dependency changes detected. Learn more about Socket for GitHub ↗︎ |
almost done, I picked everything. will review it once again and mark it as ready. I tried ts-standard instead of standard. While it uses some useful rules like |
Please fix tests |
I see you deleted the doc. Can you show what a generated doc would look like ? |
Overall doesn't look worse than before. But also it's not super clear to me what we gain here. Just adds a bunch of syntactic complexity and maybe a small amount of type safeness. What do you think @extremeheat ? |
https://github.com/zardoy/space-squid/tree/ts-master/src/lib this is the part that may maybe benefit from TS but somehow you didn't convert it. Any reason? |
Yes give me a moment. Also let's discuss it in the last step, not the biggest issue here imo.
Let's revert things you don't like here. I just want basic IntelliSense for serv/entity/player (and typings!).
Yes I fixed a small amount of bugs that types helped me to catch. But in the current state the codebase is almost fully typed so referencing would allow you to prototype faster. Or did you mean something else?
can convert them as well if needed, I think this is just 5% of the codebase. I was really focused on plugins, so if plugins code look good... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also let's remove duplicating code const registry = require('prismarine-registry')(version)
and instead set it to server like serv.resitry = ...
src/lib/plugins/log.ts
Outdated
} finally { | ||
process.stdout = tmp | ||
} | ||
// let tmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to revert i guess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what was the purpose of that? I remember it was broking output in some way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, got the issue, it worked before because the code was not in strict mode (which is not good)
@@ -66,8 +71,15 @@ module.exports.player = async function (player, serv, settings) { | |||
|
|||
function updateInventory () { | |||
playerData.inventory.forEach((item) => { | |||
const itemName = item.id.value.slice(10) // skip game brand prefix | |||
const itemValue: string | number = item.id.value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better inventory decode
src/lib/plugins/moderation.ts
Outdated
@@ -187,35 +186,35 @@ module.exports.server = function (serv, settings) { | |||
serv.banUUID(username, reason) | |||
.then(result => { | |||
if (result) { | |||
serv.emit('banned', ctx.player ? ctx.player : { username: '[@]' }, username, reason) | |||
if (ctx.player) ctx.player.chat(username + ' was banned') | |||
serv.emit('banned', (ctx.player != null) ? ctx.player : { username: '[@]' }, username, reason) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its standard-ts changed al these checks
I generated docs: yes, need to clean up a few things like EDIT: there is a lot of noise on paka because it also included internal API, gonna update in a second |
parse (str) { | ||
return str.match(/^(((.* )?~?-?\d* ~?-?\d* ~?-?\d*)|(.+ .+))$/) ? str.split(' ') : false | ||
}, | ||
action (args, ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rewrite tp implementation (fixed it)
player._client.write('tab_complete', { | ||
matches: matches.filter((match) => match.startsWith(existingContent)) | ||
matches: !registry.supportFeature('tabCompleteHasAToolTip') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix crash on completions send in newer versions
serv.playSound(sound, player.world, null, { ...opt, whitelist: player }) | ||
} | ||
|
||
// player.on('placeBlock_cancel', async ({ reference }, cancel) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented since events are not implemented in the code
player.prevGameMode = 255 | ||
player.gameMode = serv.gameMode | ||
player.findSpawnPoint = async () => { | ||
player.spawnPoint = await serv.getSpawnPoint(player.world) | ||
} | ||
player._client.on('settings', ({ viewDistance }) => { | ||
player.view = viewDistance | ||
player.sendRestMap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bugfix, chunks with new view distance should be sended
@@ -74,7 +76,7 @@ module.exports.server = function (serv) { | |||
if (arr.length === 0) throw new UserError('Could not find player') | |||
arr.forEach(entity => { | |||
entity.takeDamage({ damage: 20 }) | |||
serv.info(`Killed ${colors.bold(entity.type === 'player' ? entity.username : entity.name)}`) | |||
serv.info(`Killed ${colors.bold(entity.type === 'player' ? (entity as Player).username : entity.name ?? '<unknown>')}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
entity can be without name in some cases
function attackEntity (entityId) { | ||
const attackedEntity = serv.entities[entityId] | ||
if (!attackedEntity || (attackedEntity.gameMode !== 0 && attackedEntity.type === 'player')) return | ||
const attackedPlayer = attackedEntity.type === 'player' ? attackedEntity as Player : undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes a bit more verbose, but doesn't it look cleaner?
@@ -105,16 +105,16 @@ module.exports.server = function (serv, { version }) { | |||
usage: '/give <player> <item> [count]', | |||
tab: ['player', 'item', 'number'], | |||
op: true, | |||
parse (args, ctx) { | |||
args = args.split(' ') | |||
parse (_args, ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the ts pattern.
player.on('disconnected', () => serv.info(player.username + ' disconnected')) | ||
player.on('chat', ({ message }) => serv.info('<' + player.username + '>' + ' ' + message)) | ||
player.on('disconnected', (reason) => serv.info(player.username + ' disconnected. Reason: ' + reason)) | ||
// player.on('chat', ({ message }) => serv.info('<' + player.username + '>' + ' ' + message)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chat event not implemented yet
} else { | ||
// esbuild custom plugin | ||
const files = require(/* webpackIgnore: true */ 'esbuild-import-glob(path:.,skipFiles:index.js,external.js)') | ||
module.exports.builtinPlugins = Object.values(files) | ||
const files = require(/* webpackIgnore: true */ 'esbuild-import-glob(path:.,skipFiles:index.js,external.js,index.ts,external.ts)') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we now have build step I think it would be better to remove these workarounds and instead create index.js with all plugins included. So we don't need to handle different platforms
@@ -180,7 +181,7 @@ module.exports.player = function (player, serv, { version }) { | |||
player.changeBlock(data.position, 0, 0) | |||
const aboveBlock = await player.world.getBlock(data.position.offset(0, 1, 0)) | |||
if (aboveBlock.material === 'plant') { | |||
await player.setBlock(data.position.offset(0, 1, 0), 0, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setblock doesn't have 3rd arg, could lead to potential bug
@@ -280,22 +283,22 @@ module.exports.server = function (serv, { version }) { | |||
return !fail | |||
}) | |||
|
|||
if (type === 'near') sample.sort((a, b) => a.position.distanceTo(opt.pos) > b.position.distanceTo(opt.pos)) | |||
if (type === 'near') sample.sort((a, b) => a.position.distanceTo(opt.pos) - b.position.distanceTo(opt.pos)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this sorting was incorrect 😄 at least that one was caught by ts
@@ -251,6 +253,7 @@ module.exports.server = function (serv, { version }) { | |||
}) | |||
|
|||
sample = sample.filter(s => { | |||
changeType<Player & Entity & { team, scores }>(s) // TODO implement team & scores |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an easy way to change any type without writing a bunch of unnecessary TS stuff
const data = parseInt(params[5] || 0, 10) | ||
const stateId = registry.supportFeature('theFlattening') ? (blocks[id].minStateId + data) : (id << 4 | data) | ||
const data = parseInt(params[5] || '0', 10) | ||
const stateId = postFlatenning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setblock was setting incorrect default state, fixed
player.changeBlock = async (position, blockType, blockData) => { | ||
serv.players | ||
.filter(p => p.world === player.world && player !== p) | ||
.forEach(p => p.sendBlock(position, blockType, blockData)) | ||
.forEach(p => p.sendBlock(position, blockType/* , blockData */)) // todo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was handled incorrectly anyway
const UserError = require('./user_error') | ||
import UserError from './user_error' | ||
|
||
type Ctx<P extends boolean> = P extends true ? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i tried to not add a lot of generics, but this one here is just super useful for other plugins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
found a few unrelated to js->ts migration, they are not big, but i can remove them if they are blocking this pr
yes, I agree, typedoc is not the best generator here and its default look is really bad, but at least everything is structured. Anyway, I'm happy with making it all work, now its up to you whether to use it or not. If you still don't want to have anything like this, we can simply removing old docs (but I wouldn't be happy to keeping them up to date) |
the current build time is not ok, if everything else is ok, I will add esbuild-based pipeline for faster dev builds. also I'm curious why |
+1 to using typescript. Having even a small amount of type safety saves so much debugging time. |
You are right. If you write new modules or plugins you can catch bugs with the right types earlier. |
Tests still failing, my comments on libs/ not being converted is still valid. Should we close this ? |
I can fix tests if everything else is ok. Can you link the comments you are referring to?
Closing this one, means discarding a huge contribution, why don't you want to go in sync with my repo? |
Oh, ok, will do that, I will have time at the end of the week for this. |
closes #323
Still a lot of commits to pick, but decided to open early to run a few checks (like jsdoc description & remove docs, generator).awaiting feedbackI have published module for testing so you can see the final result if interested (including docs URL): http://npmjs.com/package/@zardoy/flying-squid