* Add height, width, size and imageType attribute to Image class
Close#1543#1204#1032
* Let ImageType enum code before the `Internals`, Also add @JvmStatic and OrNull version for match method
* Use runBIO and throws annotation for getImageInfo
* Add .kt suffix for MPP imagesImpl
* Return empty imageInfo for unsupported images
* Fix wrong file name
* apiDump
* Renaming MPP file instead of adding JvmName annotation
* Optimize readability and only use BIO at call-site
* Fix bug for detecting image type
* Detecting javax module for java 9+
* Clean up
* Disable some image types which not supported
* Use cross platform code to read images, readd support for apng
* Fix bug in reading image
* apiDump
* Fix bug in image reading and write unite test
* Fix wording
* Remove webp support and throws IllegalArgumentException for unsupported format
* Remove WEBP enum type
* Add unit test for unsupported image and correct comments
* Fix buffer input stream error when reading images
* Applying suggestions and fix jpg reading
* Add complete SOF decoding for jpg and clean up
* Caching jpg sof byte ranges
* Save `values()` as IMAGE_TYPE_ENUM_LIST for preventing clone operation
* Remove duplicated it
- Extract `SyncController`;
- Add super type `ProtocolStruct` to `ProtoBuf` and `JceStruct` to standardize `NoticeProcessorPipeline.process`
- and other implementations for pipeline
Reconnection is directed by `BotOfflineEvent`.
### Event Broadcasting
- PacketFactory `MessageSvcPushForceOffline` closes network with `ForceOfflineException`.
- `network.close(cause)` pass the cause to state observer from `QQAndroidBot.stateObserverChain`, the observer broadcasts as follows:
- Nothing if `cause` is `ForceOfflineException` or `BotClosedByEvent`(which is broadcast by user)
- `BotOfflineEvent.Dropped` if cause is NetworkException and is recoverable(which is from Netty handlers)
- `BotOfflineEvent.Force` if cause is `ForceOfflineException` is from the factory mentioned above.
- `BotOfflineEvent.Active` otherwise(any other unexpected exceptions considered as an error)
### Deciding whether to reconnect
User can listen and change `BotOfflineEvent.reconnect` to decide. Default values are determined by `BotConfiguration`.
### Event listening
- Component `BotOfflineEventMonitor` listens `BotOfflineEvent`, logs the event for users, and launches a coroutine to do `network.resumeConnection` to notify the selector to renew an instance.
- `BotOnlineWatchdog` in `SelectorNetworkHandler` is removed.
- Selector now handles `maxAttempts` correctly in such a way that `awaitResumeInstance` does not throw exception until maximum attempts reached.
- On every attempt, new exceptions are logged to provide debugging information, and further duplications are ignored.